Keith G
Keith G

Reputation: 4560

How to implement this with a pattern or maybe lambda syntax?

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

Answers (6)

Steven Robbins
Steven Robbins

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

Justin Morgan
Justin Morgan

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

Mark
Mark

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

Moo-Juice
Moo-Juice

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

Didaxis
Didaxis

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

thecoop
thecoop

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

Related Questions