使用具有不同参数的委托

时间:2012-05-07 11:44:23

标签: c# delegates lambda dry anonymous-function

我想干我的源代码。假设我有一些这些函数主要在一行中有所不同 - 我怎么能实现呢?

public Result foo (int x, int y, int z){
    Log.Say("Foo started!");                                 <<< DIFFERENCE
    DoSomeMagic();
    try {
        result = controller.foo(x, y, z);                    <<< DIFFERENCE
    } catch (Exception){
        Log.Say("Something went terribly wrong");
    }
    return result;
}


public Result bar (Person a, string whatever){
    Log.Say("Bar started!");                                 <<< DIFFERENCE
    DoSomeMagic();
    try {
        result = controller.bar(a, whatever);                <<< DIFFERENCE
    } catch (Exception) {
        Log.Say("Something went terribly wrong");
    }
    return result;
}

这让我疯了,因为它不会那么难?我现在对各种方法感到困惑;到目前为止,我试图与代表们一起做, Func,Lambda表达式,匿名函数,但我无法让它工作(猜我需要休息)。

public Result handler (Func callbackMethodWithArgs) {
    Result result = null;
    Log.Say(method + " started!");
    DoSomeMagic();
    try {
        result = invoke(callbackMethodWithArgs) as Result;
    } catch (Exception) {
        Log.Say("Something went terribly wrong");
    }
    return result;
}

public Result foo (int x, int y, int z) {
    return handler(controller.foo(x, y, z));
}

public Result bar (Person a, string whatever) {
    return handler(controller.bar(a, whatever);
}

作为补充,有可能使用匿名函数,如

,真的很棒
public Result foo (int x, int y, int z) {
    return handler(delegate () {
        controller.foo(x, y, z));
        doSomethingOther();
    });
}

有什么建议吗?谢谢! (我在类似的主题上阅读了很多问题,但我找不到任何解决问题的方法 - 所以我认为它可能是重复的 - 如果是的话,我很抱歉)

1 个答案:

答案 0 :(得分:2)

您可以使用Func<Result>

执行此操作
public Result handler (string name, Func<Result> method) {
    Result result = null;
    Log.Say(name + " started!");
    DoSomeMagic();
    try {
        result = method();
    } catch (Exception) {
        Log.Say("Something went terribly wrong");
    }
    return result;
}

然后在通话地点将他们变成代表:

public Result foo (int x, int y, int z) {
    return handler("Foo", () => controller.foo(x, y, z));
}

public Result bar (Person a, string whatever) {
    return handler("Bar", () => controller.bar(a, whatever);
}

注意:如果您使用的是.NET 2.0,则可以在使用上述代码之前手动创建Func<_>委托:

public delegate TResult Func<TResult>();

顺便说一句,以这种方式隐藏异常并不是一个好主意。您将返回null并仅记录异常,而不是重新抛出异常并让调用代码决定要执行的操作。可以适用于您的用例,但通常是一个红旗。