2011-01-06 63 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方法永远不需要知道它。