我读了一个关于Stack Overflow问题的答案,其中包含以下建议代码:
Action<Exception> logAndEat = ex =>
{
// Log Error and eat it
};
try
{
// Call to a WebService
}
catch (SoapException ex)
{
logAndEat(ex);
}
catch (HttpException ex)
{
logAndEat(ex);
}
catch (WebException ex)
{
logAndEat(ex);
}
我的问题是:对于LogAndEat使用lambda表达式而不是(在我看来更简单,更明显)私有方法的优点(如果有的话)如下:
private void LogAndEat(Exception ex)
{
// Log Error and eat it
}
编辑:到目前为止,感谢您的答案,但只是更清楚地重申我的基本问题:在这种情况下,哪种方法更好/您会推荐? lambda表达式还是私有方法?
答案 0 :(得分:13)
我猜你可以认为这个例子中的lambda表达式有点像Pascal的nested functions,因为它的代码只能通过它声明的方法来执行。
可以从同一个类中的任何方法调用私有方法,而像这样的lambda是当前方法的本地方法,因此显式只在该上下文中使用。
这是我能想到的唯一优势 - 在预期用途方面明确。
答案 1 :(得分:9)
logAndEat
捕获的变量否则将成为LogAndEat
方法的参数。你可以认为这是一种讨好的形式。
答案 2 :(得分:3)
LogAndEat可以引用定义它的函数中的私有字段。所以:
private bool caughtException;
Action<Exception> logAndEat = ex =>
{
caughtException = true;
};
try
{
// Call to a WebService
}
catch (SoapException ex)
{
logAndEat(ex);
}
catch (HttpException ex)
{
logAndEat(ex);
}
catch (WebException ex)
{
logAndEat(ex);
}
if (caughtException)
{
Console.Writeline("Ma, I caught an exception!");
}
这是一个陈腐的例子(!)但是这可能比将一堆参数传递给私有方法要整洁得多。
答案 3 :(得分:2)
要了解使用lambda表达式是否更好(就像我在original answer中所做的那样)或使用'正确'方法,我们需要根据常见错误处理代码的可重用性做出决定。
如果常见错误处理代码完全可以被应用程序中不同类中的其他函数重用,那么它应该是一个内部或公共函数,如果这使得代码组织更多,它可能在不同的类中明智的。
如果常见错误处理代码只能由同一个类中的其他函数重用,那么它应该是同一类中的私有函数。
如果常见的错误处理代码不能被任何其他函数重用,并且只能由此特定函数使用,那么您有两个选择。第一种是使用委托将其封装在函数的边界内,确保函数不泄漏任何实现细节。第二种是在同一个类中使用一个私有函数,注释只能由它所针对的函数调用。
在第三种情况下,没有明确的“最佳方式”,因为两者都是实现相同目标的完美合法方式。我倾向于在公共代码很小时使用委托和/或你需要代理的一些行为,比如捕获变量。
现在,回到问题,为什么我使用委托编写代码?我没有关于错误处理代码是否可以重复使用的信息,所以我认为它不是,并且决定使用委托,因为我认为人们会发现很容易从这里开始意识到这可能是一个“正确的”方法(如你所知)而如果我展示了使用“正确”的功能,人们可能没有意识到代表会成为另一种选择。
答案 4 :(得分:1)
很多情况归结为个人偏好,没有人可以说绝对的方式是正确的方式或错误的方式。
Lambda表达式的行为类似于其他语言中的闭包,关于它们的一个很酷的事情是它们可以访问作用于它们声明的方法的变量。这为你在代码中可以做的事情增加了很多灵活性,但是来了代价是在调试时无法修改该方法中的代码。
出于这个原因,如果您要记录错误,您可能会在某个时间或某个时间发现自己处于该方法的调试器中。如果你使用lambda,你将无法在运行时修改任何代码 - 因此我的偏好是使用一个单独的私有方法接受异常作为其参数。
答案 5 :(得分:1)
感谢大家对我投票的好答案,但我想我总结一下,试着在一个答案中捕捉利弊。
使用lambda表达式(LE)而不是私有方法的优点:
使用lambda表达式而不是私有方法的缺点:
还有更主观的可维护性问题,有人可能会认为LE并不像大多数开发人员那样理解为私有方法,因此可维护性较差。也可以认为LE提高了可维护性,因为它被封装在调用它的方法中,而不是整个类可见的私有方法。
答案 6 :(得分:0)
IMO我不喜欢微小的私有函数,这些私函数仅用于我的类中的另一个私有方法,我发现它们很难看,这就是我在该示例中使用lambda的原因
我认为使用lambda而不是函数
会对性能产生影响