【问题标题】:lambda expression and var keyword in c# [duplicate]c#中的lambda表达式和var关键字[重复]
【发布时间】:2011-10-17 09:03:44
【问题描述】:

可能重复:
C# Why can't an anonymous method be assigned to var?

我在 c# 中有以下语句

Func <int, int, int> add = (x, y) => x + y;

但是当我用下面的替换左侧语句时

var add = (x, y) => x + y;

我收到编译器错误(无法将 lambda 表达式分配给隐式类型的局部变量)。为什么?

【问题讨论】:

  • 可能是因为无法确定 x 和 y 是 ints。在有关它的问题中包含完整的错误消息总是有用的。
  • 因为需要指定参数的类型,以及返回类型
  • 酷,当您尝试将表达式树存储在 var 类型的变量中时,这似乎是一个问题。有道理,因为表达式树是在执行时评估的……但真的很酷。 ;)
  • @Rob 即使您指定 x 和 y 的类型(返回类型由表达式隐式给出),您仍然会得到“无法将 lambda 表达式分配给隐式类型变量”

标签: c# lambda


【解决方案1】:

因为编译器无法判断 RHS 的类型是什么

var add = (x, y) => x + y;

任何支持+ 运算符的类型都是候选类型,因为 x 和 y 的类型不受限制为同一类型。有很多可能的 + 运算符可以使用,因此 x 和 y 的可能类型集相当大,但为了能够确定 add 的类型,编译器需要能够将集合减少到只有一种类型用于 x 和一种类型用于 y(不完全正确,可能基类和派生类都适合),即使编译器可以找出 x 和 y 的类型或者您指定了类型假设int 你仍然会留下这样一个事实,即两者 Expression&lt;Func&lt;int,int,int&gt;&gt;Func&lt;int,int,int&gt; 是 add 的可能类型

对于如何减少可能的类型集有多种选择。编译器可以尝试查看 add 稍后是如何使用的,但没有(即使这样做也可能无法确定类型)

【讨论】:

  • 作为附录,您可以告诉编译器 var add = (Func&lt;int,int,int&gt;)((x,y) =&gt; x + y); 发生了什么,但这并不能真正为您带来任何好处,因为您不妨将 func 放在 LHS 上!
  • 但是编译器让这样的 lambda 多态不是正确的吗?
  • 顺便说一句,如果它有效,它将是对由于未知原因限制的泛型的一个很好的补充。
  • Eh...但是模棱两可是无关紧要的。具体错误为An implicitly typed local variable declaration cannot be initialized with 'anonymous method'。它没有给出错误,因为它是模棱两可的,它给出了一个错误,因为语言不允许它。说它是因为它是模棱两可的,这意味着如果你能毫不含糊地写它,它会突然就可以了。歧义与它无关,除非是语言的设计者将其定为非法的原因。但至于为什么会报错,那是因为语言不允许。
  • var formatDate = (DateTime dt) =&gt; dt.ToString("yyyy/MM/dd");。很明显,输入类型是DateTime,返回类型是string。没有理由不能将其编译为 Func&lt;DateTime,string&gt;,除了该语言还可以将 lambda 编译为 Expression>,因此总是存在歧义。
【解决方案2】:

var 关键字不起作用,因为 lambda 表达式作为表达式树用于两个委托,并且编译器不知道应该将 lambda 转换为哪个。换句话说,以下类型对您的 (x, y) =&gt; x + y lambda 有效:Func&lt;int, int, int&gt;Expression&lt;Func&lt;int, int, int&gt;&gt;

【讨论】:

  • 另外,它不知道xyint的。
  • 另外,x 和 y 类型为 int 的问题可以通过 (int x, int y) =&gt; x + y 解决。重点是 Func vs Expression
【解决方案3】:

你得到的错误是因为编译器不知道 x 和 y 是什么类型。

【讨论】:

  • @Emo:你是对的。但我们知道 var 关键字从右侧语句推断类型。
  • 即使你指定了 x 和 y 的类型,你仍然会得到一个错误:“Cannot assign lambda expression to an implicitly typed variable”
  • @geek var 将推断类型,但右侧告诉编译器没有任何关于 xy 的具体信息(只是它们定义了一个运算符 +)。
  • 这只是错误的。即使你输入var someFunc = (int x, int y) =&gt; x + y; 也不起作用。
猜你喜欢
  • 2011-04-03
  • 2010-11-11
  • 1970-01-01
  • 2011-01-21
  • 2010-11-15
  • 2013-04-19
  • 2018-09-09
  • 2010-10-27
  • 2011-09-30
相关资源
最近更新 更多