Как реализовать это с помощью шаблона или, возможно, синтаксиса лямбда? - PullRequest
0 голосов
/ 06 января 2011

У меня есть несколько методов, которые выполняют один и тот же код установки, а затем немного кода очистки.Материал между изменениями.Я мог бы сделать это так:

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);
}

Но я бы предпочел сделать что-то, где мне не нужно каждый раз вызывать методы настройки и очистки.Может быть, как один вызов, где могут быть переданы конкретные вещи метода?

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;
}

Подход method1, method2 работает отлично, я просто брожу, если есть способ улучшить его или сделать его более элегантным.

Ответы [ 6 ]

2 голосов
/ 06 января 2011

Если "x" всегда int, вы можете просто передать действие:

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

    try
    {
        methodCode(x);
    }
    finally
    {
        // cleanup code here
        x = 0;
    }
}
0 голосов
/ 06 января 2011

Как насчет чего-то вроде:

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

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

    return cleanup;
}

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

    // do something useful

    cleanup();
}

Таким образом, ваш метод настройки подготавливает свой собственный код очистки, и ваш основной метод DoSomethingUseful никогда не должен знать об этом.

0 голосов
/ 06 января 2011

Звучит так, как будто вы хотите использовать класс:

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 голосов
/ 06 января 2011

Если вы можете поместить определенный код Method1 & Method2 в свои собственные функции, и каждая из них может использовать одну и ту же сигнатуру метода, то создайте тип делегата для сигнатуры и напишите Method1 & Method2 для соответствия сигнатуре и передайте его SetupAndCleanup. Лямбда будет работать, если вы можете делать все, что вам нужно, используя лямбду. Чтобы использовать лямбду, просто помните, что лямбда следует подписи делегата.

0 голосов
/ 06 января 2011

Я бы использовал такой метод, как этот:

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 голосов
/ 06 января 2011

Вы можете использовать делегата:

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...