我读到C#lambdas可以被非法转换为Action或Func,但是lambda不能直接执行定义lambda函数并立即执行它 例如:
int n = (()=>5)(); //doesn't work
int n = ((Func<int>)(()=>5))(); //works
Run Code Online (Sandbox Code Playgroud)
那么lambda的实际类型是什么?为什么不能直接调用它?是因为C#类型系统比Haskell或Scala系统"弱"吗?
小智 27
lambda表达式没有类型.它不能,因为它可能拥有的.NET世界中的任何类型,也会硬编码lambda的参数和结果的类型.现在考虑:
x => x + 1
Run Code Online (Sandbox Code Playgroud)
什么类型可以x?结果是什么类型的?这里没有任何单一的答案,以及lambda表达式的确可以转化成Func<int, int>,Func<double, double>以及许多其他委托类型使用不同的参数.给lambda表达式一个类型会禁止这样的表达式.C#确实想要允许这样的表达式,所以设计的不是给这样的表达式任何类型.
这是因为() => 5可以与各种委托类型兼容(例如,您可能有一个delegate不带任何东西并返回的自定义int).并且为了创建一个delegate,编译器必须知道确切的类型.它不能只选择适合您需求的随机类型.所以这就是为什么除非你把它转换为实际的委托类型,否则你不能Invoke.
在方法期望a的情况下delegate,编译器隐式地完成转换:
void Foo(Func<int> func) { }
Foo(() => 5);
Run Code Online (Sandbox Code Playgroud)
同样重要的是要知道delegates实际上是幕后的课程.每次创建delegate实例时,编译器都会创建一个实例class.因此,无论哪种方式,您都必须指定一个类型,以便编译器知道要使用哪种类型.
| 归档时间: |
|
| 查看次数: |
2148 次 |
| 最近记录: |