在此代码片段中:
List<String> names = new List<String>();
names.Add("Bruce");
names.Add("Tom");
names.Add("Tim");
names.Add("Richard");
names.ForEach(x => Print(x));
private static string Print(string s)
{
Console.WriteLine(s);
return s;
}
Print
肯定不是Action
,因为它正在返回string
;无论x=> Print(x)
如何,为什么?
lambda 表达式x => Print(x)
的类型根据其上下文确定。由于编译器知道lambda被分配给Action<string>
,编译器忽略Print(s)
方法的返回类型,就好像它是一个语句表达式一样。
这是有效的转换:
Action<string> myAction = y => Print(y);
换句话说,两者兼而有之
Print("something");
和
int x = Print("something");
是 Print
方法的正确用法;它们可以以相同的方式在 lambda 中使用。
x => Print(x)
是一个 lambda,在这里变成了一个方法,相当于:
void MyPrintLambda(string x) { Print(x); }
如果上下文要求,比如说,一个Func<string, string>
,那就是这样的:
string MyPrintLambda(string x) { return Print(x); }
或者如果它是一个Func<string, object>
,它会是这样的:
object MyPrintLambda(string x) { return Print(x); }
因为编译器可以通过简单地忽略返回类型(即第一个示例)将x => Print(x)
转换为Action<string>
,所以它可以编译。
出于同样的原因,这将是有效的:
foreach (string name in names)
{
Print(name);
}
Print() 方法在该代码中也返回一个值,但没有人会认为这是一个错误。允许只丢弃返回值。