以下陈述完全没问题。
var sb = new string[] { "line1", "line2" };
sb.ForEach(Console.WriteLine);
// same as sb.ForEach(item => Console.WriteLine(item));
这种练习的名称是什么,不使用lambda表达式中的参数?
谢谢,
答案 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减少或方法组转换。你的问题是措辞,听起来有点像关闭。