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

What's the actual type of lambda in C#?

我读到 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# 类型系统 "weaker" 比 Haskell 还是 Scala 类型系统?

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

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

void Foo(Func<int> func) {  }

Foo(() => 5); 

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

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

x => x + 1

x 可能有什么类型?结果会是什么类型?没有任何单一的答案,而且 lambda 表达式确实可以转换为 Func<int, int>Func<double, double> 和许多其他具有不同参数的委托类型。给 lambda 表达式一个类型将不允许这样的表达式。 C# 确实希望允许此类表达式,因此设计为不为此类表达式提供任何类型。