2011-01-06 61 views
0

我有幾個方法執行相同的設置代碼,然後一些清理代碼。變化之間的東西。我可以這樣做:如何用模式或lambda語法實現這個?

void method1() 
{ 
    var x = DoSetupStuff(); 

    // Method 1 specific code that uses x 

    DoCleanupStuff(x); 
} 

void method2() 
{ 
    var x = DoSetupStuff(); 

    // Method 2 specific code that uses x 

    DoCleanupStuff(x); 
} 

但我寧願做一些事情,我不必每次都調用setup和cleanup方法。也許像一個調用方法特定的東西可以傳入?

void SetupAndCleanup(method-specific-code) 
{ 
    // Setup code here 
    int x = 1; 

    // method-specific code injected here. 
    // note that it uses x. 

    // cleanup code here 
    x = 0; 
} 

的方法1,方法2的方式工作得很好,我只是遊蕩,如果有改善,或使其更加優雅的方式。

回答

2

如果「x」是永遠一個int,你可以通過在行動:

void SetupAndCleanup(Action<int> methodCode) 
{ 
    // Setup code here 
    int x = 1; 

    try 
    { 
     methodCode(x); 
    } 
    finally 
    { 
     // cleanup code here 
     x = 0; 
    } 
} 
0

您可以使用委託:

void SetupAndCleanup(Action action) { 
    // setup 

    action(); 

    // cleanup 
} 

void Method1() { 
    SetupAndCleanup(() => { 
     // do my stuff here 
    }); 
} 

// or... 
private void Method2Impl() { 
    // do my stuff here 
} 

void Method2() { 
    SetupAndCleanup(Method2Impl); 
} 

或IDisposable接口:

private sealed class SetupClass : IDisposable { 
    public SetupClass() { 
     // setup 
    } 

    public void Dispose() { 
     // cleanup 
    } 
} 

void Method1() { 
    using (SetupClass setup = new SetupClass() { 
     // do stuff here 
    } 
} 

void Method2() { 
    using (SetupClass setup = new SetupClass() { 
     // do stuff here 
    } 
} 
+0

即使他只是使用動作,他也不會在lambda表達式中訪問x。 – 2011-01-06 17:15:33

0

我會使用的方法,例如這樣的:

void ExecuteMethodWithSetupAndCleanup(Action<int> method) 
{ 
    // do the setup stuff 
    var x = DoSetupStuff(); 

    // run the provided code 
    method(x); 

    // do the cleanup stuff 
    DoCleanupStuff(x); 
} 

,然後用它像這個:

void method1() 
{ 
    ExecuteMethodWithSetupAndCleanup(x => 
     { 
      // here is the method1 specific code using x 
     } 
} 


void method2() 
{ 
    ExecuteMethodWithSetupAndCleanup(x => 
     { 
      // here is the method2 specific code using x 
     } 
} 

或者,如果你已經有了method1()method2(),你想將它們分開,只有從他們身上取出安裝/清理,你可以做這樣的事情:

void method1(int x) 
{ 
    // here is the method1 specific code using x 
} 

void method2(int x) 
{ 
    // here is the method2 specific code using x 
} 

void ExecuteMethod1AndMethod2() 
{ 
    ExecuteMethodWithSetupAndCleanup(method1); 
    ExecuteMethodWithSetupAndCleanup(method2); 
} 
+0

雖然他只是使用動作,但他不會在lambda表達式中訪問x。 – 2011-01-06 17:15:08

+0

你是對的......我錯過了評論中的內容,並且修復了代碼以解釋它。 – Mark 2011-01-06 17:18:37

0

如果你可以將方法1 &方法2特定的代碼放到自己的功能,並能互相共享相同的方法簽名,然後創建簽名的委託類型,並寫信給我thod1 & Method2符合簽名並將其傳遞給SetupAndCleanup。如果您可以完成使用lambda所需的所有工作,lambda將會起作用。要使用lambda只需記住lambda遵循委託的簽名。

0

聽起來像是你可能想使用一個類:

public abstract class DoStuff 
{ 
    protected abstract void DoStuffImpl(var x); 

    private var DoSetupStuff() 
    { 
    } // eo DoSetupStuff 


    private void DoCleanupStuff(var x) 
    { 
    } // eo DoCleanupStuff 

    public DoStuff() 
    { 
    } // eo ctor 

    public void DoMethod() 
    { 
     var x = DoSetupStuff(); 
     DoStuffImpl(x); 
     DoCleanupStuff(x); 
    } // eo DoMethod 
} // eo class DoStuff 

然後提供專業:

public class Special1 : DoStuff 
{ 
    protected override DoStuffImpl(var x) 
    { 
     // work with x here 
    } 
} // eo class Special1 

public class Special2 : DoStuff 
{ 
    protected override DoStuffImpl(var x) 
    { 
     // work with x here, but in a different way 
    } 
} // eo class Special2 


// work with them 
Special1 s1; s1.DoMethod(); 
Special2 s2; s2.DoMethod(); 
0

如何像:

protected Action DoSetupStuff() 
{ 
    //... setup code 

    Action cleanup =() => 
    { 
     //... prepare cleanup code for later 
    }; 

    return cleanup; 
} 

void DoSomethingUseful() 
{ 
    var cleanup = DoSetupStuff(); 

    // do something useful 

    cleanup(); 
} 

這樣,你的設置方法準備自己的清理代碼,而您的主要DoSomethingUseful方法永遠不需要知道它。