所以当我写这样的东西时
So when I write something like this
Action action = new Action(()=>_myMessage = "hello");重构专业版!突出显示这是一个冗余的委托创建,并允许我将其缩短为
Refactor Pro! Highlights this as a redundant delegate creation and allows me to to shorten it to
Action action = () => _myMessage="hello";这通常效果很好.通常,但并非总是如此.例如,Rhino Mocks 有一个名为 Do 的扩展方法:
And this usually works great. Usually, but not always. For example, Rhino Mocks has an extension method named Do:
IMethodOptions<T> Do(Delegate action);在这里,传入第一个版本有效,但第二个无效.这里到底发生了什么?
Here, passing in the first version works, but the second doesn't. What exactly is going on under the covers here?
推荐答案第一个版本有效地做了:
The first version is effectively doing:
Action tmp = () => _myMessage = "hello"; var action = new Action(tmp);您遇到的问题是编译器必须知道 lambda 表达式应该转换成什么样的委托(或表达式树).这就是为什么:
The problem you're running into is that the compiler has to know what kind of delegate (or expression tree) the lambda expression should be converted into. That's why this:
var action = () => _myMessage="hello";实际上无法编译 - 它可以是 any 没有参数的委托类型,也可以是没有返回值或与 _myMessage 相同的返回类型(大概是 string).例如,所有这些都是有效的:
actually doesn't compile - it could be any delegate type with no parameters and either no return value or the same return type as _myMessage (which is presumably string). For instance, all of these are valid:
Action action = () => _myMessage="hello"; Func<string> action = () => _myMessage="hello"; MethodInvoker action = () => _myMessage="hello"; Expression<Action> = () => _myMessage="hello"; // etc如果使用 var 声明,C# 编译器如何计算 action 的含义?
How could the C# compiler work out what type action was meant to be, if it were declared with var?
在调用方法(对于您的 Rhino Mocks 示例)时解决此问题的最简单方法是强制转换:
The simplest way to get round this when calling a method (for your Rhino Mocks example) is to cast:
methodOptions.Do((Action) (() => _myMessage = "hello"));更多推荐
new Action() 和 lambda 有什么区别?
发布评论