0

我想干燥我的源代码。假设我有一些主要在一行中不同的功能 - 我怎么能做到这一点?

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

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

4

1 回答 1

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 并仅记录一个异常,而不是重新抛出它并让调用代码决定要做什么。可以适用于您的用例,但通常是一个危险信号。

于 2012-05-07T12:12:37.487 回答