C#中实际的lambda类型是什么?

时间:2015-01-06 09:38:52

标签: c# lambda func

我读到C#lambdas可以被非法转换为Action或Func,但是lambda不能直接执行Define a lambda function and execute it immediately 例如:

int n = (()=>5)(); //doesn't work
int n = ((Func<int>)(()=>5))(); //works

那么lambda的实际类型是什么?为什么不能直接调用它?是因为C#类型系统比Haskell或Scala系统“弱”吗?

2 个答案:

答案 0 :(得分:27)

lambda表达式没有类型。它不能,因为它可能拥有的.NET世界中的任何类型,也会硬编码lambda的参数和结果的类型。现在考虑:

x => x + 1

x可以使用哪种类型?结果是什么类型的?没有任何单一答案,lambda表达式确实可以转换为Func<int, int>Func<double, double>和许多其他具有不同参数的委托类型。给lambda表达式一个类型会禁止这样的表达式。 C#确实想要允许这样的表达式,所以设计的不是给这样的表达式任何类型。

答案 1 :(得分:9)

这是因为() => 5可以与各种代理类型兼容(例如,您可能拥有一个不带任何内容并返回delegate)的自定义int。并且为了创建delegate,编译器必须知道确切的类型。它不能选择适合您需求的随机类型。这就是为什么除非你将它转换为实际的委托类型,否则你不能Invoke它。

在方法需要delegate的情况下,编译器会隐式完成转换:

void Foo(Func<int> func) {  }

Foo(() => 5); 

同样重要的是要知道delegates实际上是幕后的类。每次创建delegate实例时,编译器都会创建该class的实例。因此,无论哪种方式,您都必须指定一个类型,以便编译器知道要使用哪种类型。