新的Action()和lambda有什么区别?

新的Action()和lambda有什么区别?

问题描述:

所以,当我写这样的事情新的Action()和lambda有什么区别?

Action action = new Action(()=>_myMessage = "hello"); 

重构临!突出这是一个冗余的代表创建,并允许我将其缩短到

Action action =() => _myMessage="hello"; 

而且这通常很好。 通常,但并非总是如此。例如,犀牛制品有一个名为做一个扩展方法:

IMethodOptions<T> Do(Delegate action); 

这里,通过在第一个版本的作品,但第二个没有。这里的封面到底是什么?

+4

你的第二个代码块不进行编译。我收到此消息“无法将lambda表达式分配给隐式类型的局部变量”。但是,如果我将“var”替换为“Action”,它就可以。 – 2009-04-19 20:04:33

+1

是的,你是对的,它不能被分配给一个隐式类型的变量,我会编辑它。 – 2009-04-20 02:12:44

第一版切实做好:

Action tmp =() => _myMessage = "hello"; 
var action = new Action(tmp); 

你正在运行到的问题是

有关此主题的详细讨论,您应该主题阅读埃里克利珀的博客文章编译器必须知道lambda表达式应该转换成什么样的委托(或表达式树)。这就是为什么这样的:

var action =() => _myMessage="hello"; 

实际上没有编译 - 它可以是任何委托型不带参数,要么没有返回值或相同的返回类型为_myMessage(这大概是string)。例如,所有的这些都是有效的:

Action action =() => _myMessage="hello"; 
Func<string> action =() => _myMessage="hello"; 
MethodInvoker action =() => _myMessage="hello"; 
Expression<Action> =() => _myMessage="hello"; 
// etc 

如何可以在C#编译器是什么类型action的意思是,如果它是用var申报?

调用一个方法(对于您的犀牛制品的例子)时避开这个最简单的方法是投:

methodOptions.Do((Action) (() => _myMessage = "hello")); 

您是否验证过第二行实际编译的内容?它不应该编译,因为C#不支持将一个lambda表达式分配给一个隐式类型变量(CS0815)。这行可以在VB.Net中工作,因为它支持创建匿名代理(从VB 9.0开始)。

由于第二行不能编译的原因,Rhino Mocks版本不能编译。 C#不会自动推断出lambda表达式的类型。 Lambda表达式必须在可以确定它们要实现的委托类型的上下文中使用。第一行很好,因为预期的类型很明确:Action。 Rhino Mocks版本不起作用,因为Delegate更类似于抽象委托类型。它必须是一个具体的委托类型,例如Action或Func。 http://blogs.msdn.com/ericlippert/archive/2007/01/11/lambda-expressions-vs-anonymous-methods-part-two.aspx