【发布时间】:2012-01-07 00:30:48
【问题描述】:
假设我有一堂课:
class MyClass {
public int MyMethod(Func<int, int> f) { return 0; }
public int MyMethod(Expression<Func<int, int>> f) { return 1; }
}
当我尝试使用 lambda 表达式调用该方法时,我收到一个编译错误,指出两个重载之间的调用不明确:
var myClass = new MyClass();
myClass.MyMethod(x => 1 + x); // Error!
当然,使用显式类型调用可以正常工作:
myClass.MyMethod((Func<int, int>)(x => 1 + x)); // OK, returns 0
myClass.MyMethod((Expression<Func<int, int>>)(x => 1 + x)); // OK, returns 1
表达式树包含更多信息(实际代码),我可能希望在可用时利用这些信息。但我也希望我的代码与代表一起工作。不幸的是,这种模棱两可造成了这种情况,所以我必须找到另一种方法来区分这两个调用,这会弄乱原本干净的 API。
C# 规范没有说明这种特定情况,所以从这个意义上说,行为确实符合规范。
但是,有一个论点是表达式树应该优先于委托。 Compile 方法充当从表达式树到委托的显式转换。表达式树包含更多信息,当您编译为委托时,您会丢失该信息。另一个方向没有转换。
有什么理由不喜欢表达式树吗?
【问题讨论】:
-
支持
Func的论点是,您可以直接执行它,而无需经过相对昂贵的编译阶段。
标签: .net lambda expression-trees