从TDelegate到Expression <tdelegate>的隐式转换声明在哪里?</tdelegate>

时间:2015-01-02 07:34:46

标签: c# .net linq lambda linq-expressions

实际上,有四个相关的问题:

1)为什么可以这样做?

Expression<Func<int, int>> incrementorExpression = (i => i + 1);

但是不能这样做?

LambdaExpression decrementorExpression = (i => i - 1);

在第二种情况下,编译器会报告:&#34;无法将lambda表达式转换为&#39; System.Linq.Expressions.LambdaExpression&#39;因为它不是委托类型&#34;

2)TDelegateExpression<TDelegate>之间的演员在哪里宣布?我想我记得过去见过它但现在似乎无法找到它。但我无法确定是否看到了它。

3)当我这样做时:

Expression<Func<int, int>> incrementExpression = (i => ++i);

编译器说,&#34;表达式树可能不包含赋值运算符。&#34; 为什么会这样?

4)然后如果我能做到这一点:

Expression<Func<int, int>> incrementorExpression = (i => i + 1);

那为什么我不能this

public Expression<Func<T>> ToExpression<T>(Func<T> func)
{
  return func;
}

2 个答案:

答案 0 :(得分:6)

你几乎已经找到了答案。

i => i + 1不是Func<int, int>。这是一个lambda表达式。 Lambda表达式可以转换为匹配的委托类型或匹配的表达式树类型。

如果将lambda表达式转换为委托类型,编译器会将其编译为具有指定效果的IL代码。

如果将lambda表达式转换为表达式树类型,则编译器会将其编译为IL,以生成表示您在lambda表达式中编写的内容的表达式树。表达式树用于以后通过库进行解析,因此表达式树与您编写的代码紧密匹配非常重要。

Func<int, int> f = i => i + 1; // okay, creates delegate.
Expression<Func<int, int>> e = i => i + 1; // okay, creates expression tree.

无法从f检索有关其执行的操作的信息。从其委托类型可知,它需要int并返回int,但除此之外,它是一个黑盒子。你输了一个数字,然后你得到一个数字,但你不再知道如何。

另一方面,

e存储1添加到名为i的参数的事实,甚至1出现在+的RHS上{1}}。

存储在e中的这些额外信息对于解释表达式树的库来说通常是必不可少的,因此从Func<int, int>Expression<Func<int, int>>的隐式转换不会起作用:所需信息不再可用。

对于LambdaExpression decrementorExpression = (i => i - 1);,这是无效的,因为编译器无法确定您是否需要Expression<Func<int, int>>Expression<Func<int, object>>Expression<MyFunc> MyFunc是您创建的自定义委托类型。

最后&#34;表达式树可能不包含赋值运算符&#34;,这主要是因为对于表达式树的预期用例,表达式包含赋值通常没有意义。但是,考虑到.NET表达式树能够表示赋值操作,这有点任意限制。

答案 1 :(得分:0)

以下是我脑海中的一些思想片段,它们有助于解决一些谜团。但我仍在等待一个完整的答案。

首先,i => i + 1不是Func<int, int>Func。后者是IL; Func是IL; TDelegate是IL。 IL无法回复表达。

前者实际上是一种表达方式。它是lamda 表达式的一些文本表示。

现在,即使是这样,也必须在这种类型的文本类型i => i + 1Expression<TDelegate>之间进行某些演员?

但我想没有,因为没有语法标记来表示文本i => i + 1。必须有一些类在编译器DOM中表示这一点,但LINQ Expression API中没有任何内容可用于此类事情。所以编译器使用它自己的AST知道,&#34;哦,我刚刚遇到过这种文本。让我解析它并将其转换为Expression。&#34;

但这就是我所拥有的,如果这是真的,那么只回答我问题的一部分。还在等待其余的谜题得到解决。