I read an answer to a question on Stack Overflow that contained the following suggested code:
我读了一个关于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);
}
My question is: what is the advantage (if any) of using a lambda expression for LogAndEat as opposed to the (in my view simpler and more obvious) private method as follows:
我的问题是:对于LogAndEat使用lambda表达式而不是(在我看来更简单,更明显)私有方法的优点(如果有的话)是什么,如下所示:
private void LogAndEat(Exception ex)
{
// Log Error and eat it
}
Edit: Thanks for the answers so far but just restating my fundamental question a little more clearly: which approach is better/would you recommend in this instance? A lambda expression or a private method?
编辑:感谢目前为止的答案,但只是更清楚地重述我的基本问题:哪种方法更好/你会在这个例子中推荐吗? lambda表达式还是私有方法?
7 个解决方案
#1
13
I guess you could think of the lambda expression in this example as being a little bit like Pascal's nested functions, in that it's code that can only be executed by the method it's declared in.
我想你可以认为这个例子中的lambda表达式有点像Pascal的嵌套函数,因为它的代码只能通过它声明的方法来执行。
A private method could be called from any method in the same class, while a lambda like this is local to the current method and is therefore explicitly only used in that context.
可以从同一个类中的任何方法调用私有方法,而像这样的lambda是当前方法的本地方法,因此显式仅在该上下文中使用。
That's really the only advantage I can think of - being explicit in terms of expected usage.
这是我能想到的唯一优势 - 在预期用途方面明确。
#2
9
Variables captured by logAndEat
would otherwise be parameters to the LogAndEat
method. You could consider it a form of currying.
logAndEat捕获的变量否则将成为LogAndEat方法的参数。你可以认为这是一种形式的讨论。
#3
3
LogAndEat can reference private fields within the function where it's defined. So:
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!");
}
This is a trite example (!) but this potentially can be a lot tidier than passing a bunch of parameters through to a private method.
这是一个陈腐的例子(!),但这可能比将一堆参数传递给私有方法要简单得多。
#4
2
To understand whether it's better to use a lambda expression (as I did in the original answer) or use a 'proper' method, we need to make a decision based on how reusable the common error handling code is.
要了解使用lambda表达式是否更好(正如我在原始答案中所做的那样)或使用“正确”方法,我们需要根据常见错误处理代码的可重用性做出决策。
-
If the common error handling code is completely reusable by other functions in different classes across the application, then it should probably be an internal or public function, which may be in a different class if that makes the code organisation more sensible.
如果常见错误处理代码完全可以被应用程序中不同类中的其他函数重用,则它应该是内部函数或公共函数,如果这使得代码组织更加合理,则可能在不同的类中。
-
If the common error handling code is reusable by other function in the same class only, then it should probably be a private function in the same class.
如果常见的错误处理代码只能由同一个类中的其他函数重用,那么它应该是同一个类中的私有函数。
-
If the common error handling code is not reusable by any other function, and should only ever be used by this particular function, then you have two choices. The first is to use a delegate to encapsulate it within the boundaries of the function, ensuring that the function does not leak any implementation details. The second is to use a private function in the same class with a comment that it should only be called by the function it is intended for.
如果常见错误处理代码不能被任何其他函数重用,并且只能由此特定函数使用,那么您有两个选择。第一种是使用委托将其封装在函数的边界内,确保函数不泄漏任何实现细节。第二种方法是在同一个类中使用一个私有函数,注释只能由它所针对的函数调用。
In the third case, there is no clear 'best way' to do it as both are perfectly legitimate ways to achieve the same goal. My tendency would be to use a delegate when the common code is small and/or you need some of the behaviour of delegates like capturing variables.
在第三种情况下,没有明确的“最佳方式”,因为两者都是实现相同目标的完美合法方式。我倾向于在公共代码很小时使用委托和/或你需要代理的一些行为,比如捕获变量。
Now, coming back to the question, why I wrote the code using a delegate? I had no information about whether the error handling code was re-usable, so I assumed that it was not, and decided to use a delegate as I figured people would find it easy to go from this to realising it could be a 'proper' method (as you have) whereas if I showed use of a 'proper' function people may not realise that a delegate would be an alternative.
现在,回到问题,为什么我使用委托编写代码?我没有关于错误处理代码是否可重复使用的信息,所以我认为它不是,并且决定使用委托,因为我认为人们会觉得很容易从这里开始意识到它可能是一个“正确的”方法(如你所知)而如果我展示了使用“正确”的功能,人们可能没有意识到代表会成为另一种选择。
#5
1
A lot comes down to personal preference, nobody can say one absolute way is the right way or the wrong way.
很多都归结为个人偏好,没有人能说绝对的方式是正确的方式或错误的方式。
Lambda Expressions behave like closures in other languages, the cool thing about them is that they can access variables scoped to the method they're declared in. This adds a lot of flexibility to what you can do in your code, but comes at a cost of not being able to modify code in that method while debugging.
Lambda表达式的行为类似于其他语言中的闭包,关于它们的一个很酷的事情是它们可以访问作用于它们声明的方法的变量。这为您在代码中可以执行的操作增加了很多灵活性,但需要付出代价在调试时无法修改该方法中的代码。
For that reason, if you're going to be logging errors, you might find yourself in a debugger in that method at some time or another. If you use a lambda, you won't be able to modify any code at runtime - so for this reason my preference would be to use a separate private method that accepts the exception as its parameter.
因此,如果您要记录错误,您可能会在某个时间或某个时间发现自己处于该方法的调试器中。如果你使用lambda,你将无法在运行时修改任何代码 - 因此我的偏好是使用一个单独的私有方法接受异常作为其参数。
#6
1
Thanks everyone for the great answers which I have up-voted, but I thought I'd summarize them to try and capture the pros and cons in one answer.
感谢大家对我投票的好答案,但我想我总结一下,试着在一个答案中捕捉利弊。
Pros of using a lambda expression (LE) instead of a private method:
使用lambda表达式(LE)而不是私有方法的优点:
- A LE is scoped to the method in which it is declared so if it is only used by that method then that intent is made explicit by a lambda expression (even though it is possible to pass out a delegate to the LE, one can still argue the intent of declaring a LE in a method is that the LE is scoped to the method). That is, being explicit in terms of its expected usage.
- LE的范围是声明它的方法,所以如果它只被那个方法使用,那么这个意图是由lambda表达式显式化的(即使可以将一个委托传递给LE,人们仍然可以争论在方法中声明LE的意图是LE的范围是方法)。也就是说,就其预期用途而言是明确的。
- Lambda expressions behave like closures so they can access variables scoped to the method they are declared in. This can be neater than passing lots of parameters to a private method.
- Lambda表达式的行为类似于闭包,因此它们可以访问作用于它们声明的方法的变量。这可能比将大量参数传递给私有方法更简洁。
- Variables captured by a LE would otherwise be parameters to a private method and this can be exploited to allow a form of currying.
- 由LE捕获的变量否则将成为私有方法的参数,并且这可以被利用以允许一种形式的currying。
Cons of using a lambda expression instead of a private method:
使用lambda表达式而不是私有方法的缺点:
- Because the LE can access variables scoped to the method in which they are contained, it is not possible to modify code in the calling method while debugging.
- 因为LE可以访问作用于包含它们的方法的变量,所以在调试时无法修改调用方法中的代码。
There is also the more subjective issue of maintainability and one could argue that LE are not as well understood by most developers as a private method and thus are somewhat less maintainable. One could also argue that a LE improves maintainability because it is encapsulated in the method in which it is called as opposed to a private method which is visible to the entire class.
还有一个更主观的可维护性问题,有人可能认为LE并不像大多数开发人员那样理解为私有方法,因此可维护性稍差。人们还可以争辩说,LE提高了可维护性,因为它被封装在调用它的方法中,而不是整个类可见的私有方法。
#7
0
IMO I don't like tiny little private functions that are only used in another private method wondering around my classes I just find them ugly, that's why I'd use the lambda in that sample
IMO我不喜欢微小的私有函数,它们仅用于另一个私有方法,在我的类中徘徊,我发现它们很难看,这就是为什么我在那个样本中使用lambda
I don't think there's gonna be a performance impact in using the lambda instead of a function
我不认为使用lambda而不是函数会对性能产生影响
#1
13
I guess you could think of the lambda expression in this example as being a little bit like Pascal's nested functions, in that it's code that can only be executed by the method it's declared in.
我想你可以认为这个例子中的lambda表达式有点像Pascal的嵌套函数,因为它的代码只能通过它声明的方法来执行。
A private method could be called from any method in the same class, while a lambda like this is local to the current method and is therefore explicitly only used in that context.
可以从同一个类中的任何方法调用私有方法,而像这样的lambda是当前方法的本地方法,因此显式仅在该上下文中使用。
That's really the only advantage I can think of - being explicit in terms of expected usage.
这是我能想到的唯一优势 - 在预期用途方面明确。
#2
9
Variables captured by logAndEat
would otherwise be parameters to the LogAndEat
method. You could consider it a form of currying.
logAndEat捕获的变量否则将成为LogAndEat方法的参数。你可以认为这是一种形式的讨论。
#3
3
LogAndEat can reference private fields within the function where it's defined. So:
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!");
}
This is a trite example (!) but this potentially can be a lot tidier than passing a bunch of parameters through to a private method.
这是一个陈腐的例子(!),但这可能比将一堆参数传递给私有方法要简单得多。
#4
2
To understand whether it's better to use a lambda expression (as I did in the original answer) or use a 'proper' method, we need to make a decision based on how reusable the common error handling code is.
要了解使用lambda表达式是否更好(正如我在原始答案中所做的那样)或使用“正确”方法,我们需要根据常见错误处理代码的可重用性做出决策。
-
If the common error handling code is completely reusable by other functions in different classes across the application, then it should probably be an internal or public function, which may be in a different class if that makes the code organisation more sensible.
如果常见错误处理代码完全可以被应用程序中不同类中的其他函数重用,则它应该是内部函数或公共函数,如果这使得代码组织更加合理,则可能在不同的类中。
-
If the common error handling code is reusable by other function in the same class only, then it should probably be a private function in the same class.
如果常见的错误处理代码只能由同一个类中的其他函数重用,那么它应该是同一个类中的私有函数。
-
If the common error handling code is not reusable by any other function, and should only ever be used by this particular function, then you have two choices. The first is to use a delegate to encapsulate it within the boundaries of the function, ensuring that the function does not leak any implementation details. The second is to use a private function in the same class with a comment that it should only be called by the function it is intended for.
如果常见错误处理代码不能被任何其他函数重用,并且只能由此特定函数使用,那么您有两个选择。第一种是使用委托将其封装在函数的边界内,确保函数不泄漏任何实现细节。第二种方法是在同一个类中使用一个私有函数,注释只能由它所针对的函数调用。
In the third case, there is no clear 'best way' to do it as both are perfectly legitimate ways to achieve the same goal. My tendency would be to use a delegate when the common code is small and/or you need some of the behaviour of delegates like capturing variables.
在第三种情况下,没有明确的“最佳方式”,因为两者都是实现相同目标的完美合法方式。我倾向于在公共代码很小时使用委托和/或你需要代理的一些行为,比如捕获变量。
Now, coming back to the question, why I wrote the code using a delegate? I had no information about whether the error handling code was re-usable, so I assumed that it was not, and decided to use a delegate as I figured people would find it easy to go from this to realising it could be a 'proper' method (as you have) whereas if I showed use of a 'proper' function people may not realise that a delegate would be an alternative.
现在,回到问题,为什么我使用委托编写代码?我没有关于错误处理代码是否可重复使用的信息,所以我认为它不是,并且决定使用委托,因为我认为人们会觉得很容易从这里开始意识到它可能是一个“正确的”方法(如你所知)而如果我展示了使用“正确”的功能,人们可能没有意识到代表会成为另一种选择。
#5
1
A lot comes down to personal preference, nobody can say one absolute way is the right way or the wrong way.
很多都归结为个人偏好,没有人能说绝对的方式是正确的方式或错误的方式。
Lambda Expressions behave like closures in other languages, the cool thing about them is that they can access variables scoped to the method they're declared in. This adds a lot of flexibility to what you can do in your code, but comes at a cost of not being able to modify code in that method while debugging.
Lambda表达式的行为类似于其他语言中的闭包,关于它们的一个很酷的事情是它们可以访问作用于它们声明的方法的变量。这为您在代码中可以执行的操作增加了很多灵活性,但需要付出代价在调试时无法修改该方法中的代码。
For that reason, if you're going to be logging errors, you might find yourself in a debugger in that method at some time or another. If you use a lambda, you won't be able to modify any code at runtime - so for this reason my preference would be to use a separate private method that accepts the exception as its parameter.
因此,如果您要记录错误,您可能会在某个时间或某个时间发现自己处于该方法的调试器中。如果你使用lambda,你将无法在运行时修改任何代码 - 因此我的偏好是使用一个单独的私有方法接受异常作为其参数。
#6
1
Thanks everyone for the great answers which I have up-voted, but I thought I'd summarize them to try and capture the pros and cons in one answer.
感谢大家对我投票的好答案,但我想我总结一下,试着在一个答案中捕捉利弊。
Pros of using a lambda expression (LE) instead of a private method:
使用lambda表达式(LE)而不是私有方法的优点:
- A LE is scoped to the method in which it is declared so if it is only used by that method then that intent is made explicit by a lambda expression (even though it is possible to pass out a delegate to the LE, one can still argue the intent of declaring a LE in a method is that the LE is scoped to the method). That is, being explicit in terms of its expected usage.
- LE的范围是声明它的方法,所以如果它只被那个方法使用,那么这个意图是由lambda表达式显式化的(即使可以将一个委托传递给LE,人们仍然可以争论在方法中声明LE的意图是LE的范围是方法)。也就是说,就其预期用途而言是明确的。
- Lambda expressions behave like closures so they can access variables scoped to the method they are declared in. This can be neater than passing lots of parameters to a private method.
- Lambda表达式的行为类似于闭包,因此它们可以访问作用于它们声明的方法的变量。这可能比将大量参数传递给私有方法更简洁。
- Variables captured by a LE would otherwise be parameters to a private method and this can be exploited to allow a form of currying.
- 由LE捕获的变量否则将成为私有方法的参数,并且这可以被利用以允许一种形式的currying。
Cons of using a lambda expression instead of a private method:
使用lambda表达式而不是私有方法的缺点:
- Because the LE can access variables scoped to the method in which they are contained, it is not possible to modify code in the calling method while debugging.
- 因为LE可以访问作用于包含它们的方法的变量,所以在调试时无法修改调用方法中的代码。
There is also the more subjective issue of maintainability and one could argue that LE are not as well understood by most developers as a private method and thus are somewhat less maintainable. One could also argue that a LE improves maintainability because it is encapsulated in the method in which it is called as opposed to a private method which is visible to the entire class.
还有一个更主观的可维护性问题,有人可能认为LE并不像大多数开发人员那样理解为私有方法,因此可维护性稍差。人们还可以争辩说,LE提高了可维护性,因为它被封装在调用它的方法中,而不是整个类可见的私有方法。
#7
0
IMO I don't like tiny little private functions that are only used in another private method wondering around my classes I just find them ugly, that's why I'd use the lambda in that sample
IMO我不喜欢微小的私有函数,它们仅用于另一个私有方法,在我的类中徘徊,我发现它们很难看,这就是为什么我在那个样本中使用lambda
I don't think there's gonna be a performance impact in using the lambda instead of a function
我不认为使用lambda而不是函数会对性能产生影响