Expression类的目的是什么?
我想知道什么是包装Expression<>
内的委托和不是?
我看到Expression<Foo>
被Linq使用了很多,但到目前为止我还没有find任何解释这种差异的文章,只是使用了一个委托。
例如
Func<int, bool> Is42 = (value) => value == 42;
与
Expression<Func<int, bool>> Is42 = (value) => value == 42;
通过将lambda存储为一个委托,您正在存储一个委托的特定实例来执行一些操作。 它不能被修改,你只需要调用它。 一旦你有了你的委托,你在检查它做什么和不做什么的select有限。
通过将lambda存储为expression式,您将存储表示代表的expression式树。 可以操纵它来做其他事情,比如改变参数,改变身体,使它做一些完全不同的事情。 它甚至可以编译回代表,所以你可以调用它,如果你愿意。 您可以轻松地检查expression式,看看它的参数是什么,它做了什么以及如何做。 这是查询提供程序可以用来理解expression式并将其转换为另一种语言(如为对应的expression式树编写SQL查询)的东西。
使用expression式dynamic创build代理比发出代码更容易。 您可以将代码视为更高级别的expression式,这与编译器查看代码非常类似,而不是低级别,并将代码视为IL指令。
所以用一个expression式,你可以做比一个简单的匿名委托更多的事情。 虽然它不是真的免费,但是如果您运行编译的expression式(与常规方法或匿名委托相比),性能将会受到影响。 但是,这可能不是一个问题,因为使用expression式的其他好处可能对您很重要。
Func<>
只是一个委托types。 expression式是完整操作树的运行时表示,可以在运行时将其编译为委托。 这是由像Linq-to-SQL这样的expression式parsing器来parsing的树来生成SQL语句或者做其他聪明的事情。 当您将一个lambda分配给一个Expressiontypes时,编译器会生成这个expression式树以及通常的IL代码。 更多expression树 。
为了说明其他的答案,如果你编译这两个expression式并查看编译器生成的代码,那么你将看到:
Func<int, bool> Is42 = (value) => value == 42;
Func<int, bool> Is42 = new Func<int, bool>((@value) => value == 42);
Expression<Func<int, bool>> Is42 = (value) => value == 42;
ParameterExpression[] parameterExpressionArray; ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "value"); Expression<Func<int, bool>> Is42 = Expression.Lambda<Func<int, bool>>(Expression.Equal(parameterExpression, Expression.Constant(42, typeof(int))), new ParameterExpression[] { parameterExpression });
提供从中派生表示expression式树节点的类的基类。
System.Linq.Expressions.BinaryExpression System.Linq.Expressions.BlockExpression System.Linq.Expressions.ConditionalExpression System.Linq.Expressions.ConstantExpression System.Linq.Expressions.DebugInfoExpression System.Linq.Expressions.DefaultExpression System.Linq.Expressions.DynamicExpression System.Linq.Expressions.GotoExpression System.Linq.Expressions.IndexExpression System.Linq.Expressions.InvocationExpression System.Linq.Expressions.LabelExpression System.Linq.Expressions.LambdaExpression System.Linq.Expressions.ListInitExpression System.Linq.Expressions.LoopExpression System.Linq.Expressions.MemberExpression System.Linq.Expressions.MemberInitExpression System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.NewArrayExpression System.Linq.Expressions.NewExpression System.Linq.Expressions.ParameterExpression System.Linq.Expressions.RuntimeVariablesExpression System.Linq.Expressions.SwitchExpression System.Linq.Expressions.TryExpression System.Linq.Expressions.TypeBinaryExpression System.Linq.Expressions.UnaryExpression
http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx
expression式树表示可以分析并转换成SQL查询的linqexpression式。
expression式树允许您在代码中检查expression式内的代码。
例如,如果您传递了以下expression式: o => o.Name
,那么您的代码可能会发现Name
属性在expression式中被访问。
无论其他人写了什么(这是完全正确的),我会通过Expression
类添加,您可以在运行时创build新的方法。 有一些限制。 并不是所有在C#中可以做的事情都可以在Expression
树中完成(至less在.NET 3.5中,.NET 4.0中添加了大量可能的Expression
“types”)。 使用这个可以(例如)创build一个dynamic查询并将其传递给LINQ-to-SQL,或者根据用户的input做一些过滤…(如果你想要的话,你总是可以用CodeDom来做到这一点是一种与LINQ-to-SQL不兼容的dynamic方法,但直接发送IL代码相当困难:-))