为什么匿名类不能拥有一个lambda属性,但可以拥有一个Func<>属性?

19

我想学习C#对匿名类型的限制。考虑以下代码:

  var myAwesomeObject = new {
      fn1 = new Func<int>(() => { return 5; }),
      fn2 = () => { return 5; } 
  };

我们有两个实际上是函数的属性:

  • fn1: 一个返回 5Func<int>
  • fn2: 一个返回 5 的 lambda 函数。

C# 编译器可以正常处理 fn1,但是对于 fn2 报错:

无法将 Lambda 表达式分配给匿名类型属性。

有人能解释一下为什么其中一个可以而另一个不行吗?


3
编译器无法找到与匿名方法匹配的类型。如果您在可以确定此类类型的上下文中使用匿名方法,例如在方法调用中,它会强制或使用类型;但在本例中,它不会选择匹配的类型。如果您这样做:var fn2 = () => { return 5; };,也会遇到相同的问题。 - Lasse V. Karlsen
C#编译器不知道lambda表达式是代理还是表达式树。解决方案是实例化你想要创建的那个。 - Joe
2
@Thomas是正确的,但这里有一个更完整的答案来自Eric Lippert:https://dev59.com/questions/EW445IYBdhLWcg3wQX6G#4966409 - Adam Rackis
1个回答

22
由于编译器无法知道() => { return 5; }的类型,它可能是一个Func<int>,但也可能是任何其他具有相同签名的委托(也可能是表达式树)。这就是为什么您必须明确指定类型的原因。

啊… 所以这是一个类型推断问题。在此示例中,你有什么最优雅的代码建议?是否有任何我可以做的事来完善 fn1 的定义? - Stephen Gross
2
@StephenGross,你也可以将lambda表达式转换为委托类型:fn1 = (Func<int>)(() => { return 5; }); 但我更喜欢像你在问题中所做的那样显式地创建委托。 - Thomas Levesque
甚至更多,它可能根本不是委托; 它可能是一个 Expression<Func<int>> - Gabe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接