所以当我写这样的东西时
Action action = new Action(()=>_myMessage = "hello");
重构专家!将其突出显示为冗余委托(delegate)创建,并允许我将其缩短为
Action action = () => _myMessage="hello";
这通常效果很好。 通常,但并非总是如此。例如,Rhino Mocks 有一个名为 Do 的扩展方法:
IMethodOptions<T> Do(Delegate action);
在这里,传入第一个版本有效,但第二个版本无效。幕后到底发生了什么?
最佳答案
第一个版本有效地做了:
Action tmp = () => _myMessage = "hello";
var action = new Action(tmp);
您遇到的问题是编译器必须知道应该将 lambda 表达式转换成哪种委托(delegate)(或表达式树)。这就是为什么:
var action = () => _myMessage="hello";
实际上不编译 - 它可以是任何委托(delegate)类型,没有参数,没有返回值或返回类型与 _myMessage
相同(大概是 字符串
)。例如,所有这些都是有效的:
Action action = () => _myMessage="hello";
Func<string> action = () => _myMessage="hello";
MethodInvoker action = () => _myMessage="hello";
Expression<Action> = () => _myMessage="hello";
// etc
如果 action
是用 var
声明的,C# 编译器如何确定它应该是什么类型?
在调用方法时(对于你的 Rhino Mocks 示例),绕过这个问题的最简单方法是强制转换:
methodOptions.Do((Action) (() => _myMessage = "hello"));
关于c# - new Action() 和 lambda 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/765966/