为什么lambdas可以将函数调用转换为Actions?

Ada*_*Lee 13 .net c# c#-4.0

在这段代码中:

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;
}
Run Code Online (Sandbox Code Playgroud)

PrintAction因为它正在回归string,所以不是肯定的; 但是x=> Print(x),为什么呢?

das*_*ght 16

lambda表达式的类型x => Print(x)基于其上下文确定.由于编译器知道lambda被赋值Action<string>,编译器忽略了Print(s)方法的返回类型,就好像它是一个语句表达式一样.

这是一个有效的转换:

Action<string> myAction = y => Print(y);
Run Code Online (Sandbox Code Playgroud)

换句话说,两者都有

Print("something");
Run Code Online (Sandbox Code Playgroud)

和

int x = Print("something");
Run Code Online (Sandbox Code Playgroud)

是Print方法的正确用法; 它们可以以同样的方式用于lambdas.

  • 因为与字符串有关的合法事情是扔掉它.您不需要明确声明您丢弃了返回值 - 不使用它就足够了. (4认同)

Tim*_* S. 10

x => Print(x) 是一个lambda,在这里转化为一个方法,相当于:

void MyPrintLambda(string x) { Print(x); }
Run Code Online (Sandbox Code Playgroud)

如果上下文要求,比如a Func<string, string>,那就是这样的:

string MyPrintLambda(string x) { return Print(x); }
Run Code Online (Sandbox Code Playgroud)

或者,如果它是Func<string, object>,它将是这样的:

object MyPrintLambda(string x) { return Print(x); }
Run Code Online (Sandbox Code Playgroud)

因为编译器可以通过简单地忽略返回类型(即第一个例子)x => Print(x)变成一个Action<string>,它可以编译.