什么是允许消除lambda表达式中的参数的技术的名称?

时间:2012-07-05 20:01:17

标签: c# lambda

以下陈述完全没问题。

var sb = new string[] { "line1", "line2" };
sb.ForEach(Console.WriteLine); 
// same as sb.ForEach(item => Console.WriteLine(item));

这种练习的名称是什么,不使用lambda表达式中的参数?

谢谢,

3 个答案:

答案 0 :(得分:10)

“方法组转换”是您正在寻找的术语。它会自动将一组方法(重载)转换为委托。

在这种情况下,Console.WriteLine是一组包含大约19种不同方法的方法,这些方法都使用相同的名称进行重载。然后,编译器会确定其中一个重载是否与预期的委托兼容(Action<String>是唯一的委托)。由于有一个匹配,因此会将Console.WriteLine转换为new Action<String>(Console.WriteLine)

答案 1 :(得分:8)

Method(x => f(x))形式的lambda转换为Method(f)称为eta reduction。我不知道C#编译器是否在内部执行eta缩减,但它确实支持将方法组(在您的情况下为Console.WriteLine)转换为委托类型(此处可能为Action<string>)。

C#编译器会将重载Console.WriteLine(string)包装在Action<string>委托中,并将其传递给ForEach方法。

C#规范定义了将方法组转换为兼容委托类型的规则:

  

6.6方法组转化

     

从方法组(第7.1节)到a存在隐式转换(第6.1节)   兼容的委托类型。给定一个委托类型D和一个表达式E.   被分类为方法组的,存在隐式转换   如果E包含至少一种适用的方法,则从E到D.   它的正常形式(§7.5.3.1)到使用的构造的参数列表   D

的参数类型和修饰符

答案 2 :(得分:0)

虽然之前的答案都很好 - 而且正确 - 如果您有以下代码,还有一个额外的答案:

int i = 7;
return () => Foo(i);

这就是所谓的闭包,因为虽然lambda没有参数,但它将整数括在父作用域中。当使用返回的匿名方法时,它仍然可以使用变量i,就好像它永远不会超出范围......并且因为它是封闭的,它没有!

根据您的原始问题,您演示的是eta减少或方法组转换。你的问题是措辞,听起来有点像关闭。