Reputation: 4560
I have several methods that execute the same setup code and then some cleanup code. The stuff in between changes. I could do it like this:
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);
}
But I'd rather do something where I don't have to call both setup and cleanup methods every time. Maybe like one call where the method specific stuff can be passed in?
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;
}
The method1, method2 approach works perfectly well, I'm just wandering if there is a way to improve it or make it more elegant.
Upvotes: 0
Views: 176
Reputation: 26599
If "x" is always an int you can just pass in an Action:
void SetupAndCleanup( Action<int> methodCode )
{
// Setup code here
int x = 1;
try
{
methodCode(x);
}
finally
{
// cleanup code here
x = 0;
}
}
Upvotes: 2
Reputation: 30700
How about something like:
protected Action DoSetupStuff()
{
//... setup code
Action cleanup = () =>
{
//... prepare cleanup code for later
};
return cleanup;
}
void DoSomethingUseful()
{
var cleanup = DoSetupStuff();
// do something useful
cleanup();
}
This way, your setup method prepares its own cleanup code, and your primary DoSomethingUseful method never has to know about it.
Upvotes: 0
Reputation: 11750
I'd use a method such as this:
void ExecuteMethodWithSetupAndCleanup(Action<int> method)
{
// do the setup stuff
var x = DoSetupStuff();
// run the provided code
method(x);
// do the cleanup stuff
DoCleanupStuff(x);
}
And then use it like this:
void method1()
{
ExecuteMethodWithSetupAndCleanup(x =>
{
// here is the method1 specific code using x
}
}
void method2()
{
ExecuteMethodWithSetupAndCleanup(x =>
{
// here is the method2 specific code using x
}
}
Alternatively, if you already have method1()
and method2()
and you want to keep them separate, and only remove the setup/cleanup from them, you can do something like this:
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);
}
Upvotes: 0
Reputation: 38820
Sounds like you might want to use a class:
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
Then provide specializations:
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();
Upvotes: 0
Reputation: 8756
If you can place the Method1 & Method2 specific code into their own functions, and each could share the same method signature, then create a delegate type of the signature, and write Method1 & Method2 to conform to the signature and pass it to SetupAndCleanup. A lambda will work if you can do everything you need to using the lambda. To use the lambda just remember that the lambda follows the signature of the delegate.
Upvotes: 0
Reputation: 46128
You can use a delegate:
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);
}
or an 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
}
}
Upvotes: 0