C# 表达式树的实际使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/403088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Practical use of expression trees
提问by Dmitri Nesteruk
Expression trees are a nice feature, but what are its practical uses? Can they be used for some sort of code generation or metaprogramming or some such?
表达式树是一个不错的特性,但它的实际用途是什么?它们可以用于某种代码生成或元编程之类的吗?
回答by tuinstoel
You can use them to build your own linq provider for a website like Google or Flickr or Amazon, your own website or another data provider.
您可以使用它们为 Google、Flickr 或 Amazon 等网站、您自己的网站或其他数据提供程序构建您自己的 linq 提供程序。
回答by Jon Skeet
Marc Gravell has used them to great effect in MiscUtilto implement generic operators.
Marc Gravell 在MiscUtil 中使用它们来实现泛型运算符的效果非常好。
回答by Mauricio Scheffer
Implementation of LINQ providers is mostly done by processing expression trees. I'm also using them to remove literal strings from my code:
LINQ 提供程序的实现主要是通过处理表达式树来完成的。我还使用它们从我的代码中删除文字字符串:
回答by Marc Gravell
As Jon notes, I use them to provide generic operatorswith .NET 3.5. I also use them (again in MiscUtil) to provide fast access to non-default constructors (you can't use Delegate.CreateDelegate
with constructors, but Expression
works fine).
正如 Jon 所指出的,我使用它们为.NET 3.5提供通用运算符。我还使用它们(再次在 MiscUtil 中)来提供对非默认构造函数的快速访问(您不能Delegate.CreateDelegate
与构造函数一起使用,但Expression
工作正常)。
Other uses of manually created expression trees:
手动创建的表达式树的其他用途:
But really, Expression is a very versatile way of writing any dynamic code. Much simpler than Reflection.Emit
, and for my money, simpler to understand than CodeDOM. And in .NET 4.0, you have even more optionsavailable. I show the fundamentals of writing code via Expression
on my blog.
但实际上,Expression 是编写任何动态代码的一种非常通用的方式。Reflection.Emit
比 CodeDOM简单得多,而且对我来说,比 CodeDOM 更容易理解。在 .NET 4.0 中,您有更多可用选项。我Expression
在我的博客上展示了编写代码的基础知识。
回答by mattruma
I use them to create dynamic queries, whether it be for sorting or filtering the data. As an example:
我使用它们来创建动态查询,无论是排序还是过滤数据。举个例子:
IQueryable<Data.Task> query = ctx.DataContext.Tasks;
if (criteria.ProjectId != Guid.Empty)
query = query.Where(row => row.ProjectId == criteria.ProjectId);
if (criteria.Status != TaskStatus.NotSet)
query = query.Where(row => row.Status == (int)criteria.Status);
if (criteria.DueDate.DateFrom != DateTime.MinValue)
query = query.Where(row => row.DueDate >= criteria.DueDate.DateFrom);
if (criteria.DueDate.DateTo != DateTime.MaxValue)
query = query.Where(row => row.DueDate <= criteria.DueDate.DateTo);
if (criteria.OpenDate.DateFrom != DateTime.MinValue)
query = query.Where(row => row.OpenDate >= criteria.OpenDate.DateFrom);
var data = query.Select(row => TaskInfo.FetchTaskInfo(row));
回答by damageboy
Originally by Jomo Fisher, Gustavo Guerrapublished a revised version of the static string dictionary.
最初由乔莫·费舍尔,古斯塔沃·格拉公布的修订版静态字符串字典。
Where through Expression trees, a dynamic expression that provides a really (read: ridiculously) Dictionary.
通过表达式树,动态表达式提供了一个真正(阅读:可笑)的字典。
The implementation creates a dynamic decision tree that select the corrent value according to the length of the input string, then by the first letter, then the second letter and so on.
该实现创建了一个动态决策树,它根据输入字符串的长度选择正确的值,然后是第一个字母,然后是第二个字母,依此类推。
This ultimately runs much faster than the equivalent Dictionary.
这最终比等效的 Dictionary 运行得快得多。
回答by Moumit
I just created a generic filter function using an Expression Tree that I want to share with you guys...
我刚刚使用表达式树创建了一个通用过滤器函数,我想与你们分享......
Start
开始
var allFiltered= Filter(AllCustomer, "Name", "Moumit");
public static List<T> Filter<T>(this List<T> Filterable, string PropertyName, object ParameterValue)
{
ConstantExpression c = Expression.Constant(ParameterValue);
ParameterExpression p = Expression.Parameter(typeof(T), "xx");
MemberExpression m = Expression.PropertyOrField(p, PropertyName);
var Lambda = Expression.Lambda<Func<T, Boolean>>(Expression.Equal(c, m), new[] { p });
Func<T, Boolean> func = Lambda.Compile();
return Filterable.Where(func).ToList();
}
One More
多一个
string singlePropertyName=GetPropertyName((Property.Customer p) => p.Name);
public static string GetPropertyName<T, U>(Expression<Func<T, U>> expression)
{
MemberExpression body = expression.Body as MemberExpression;
// if expression is not a member expression
if (body == null)
{
UnaryExpression ubody = (UnaryExpression)expression.Body;
body = ubody.Operand as MemberExpression;
}
return string.Join(".", body.ToString().Split('.').Skip(1));
}
Make it more expandable
使其更具扩展性
string multiCommaSeparatedPropertyNames=GetMultiplePropertyName<Property.Customer>(c => c.CustomerId, c => c.AuthorizationStatus)
public static string GetMultiplePropertyName<T>(params Expression<Func<T, object>>[] expressions)
{
string[] propertyNames = new string[expressions.Count()];
for (int i = 0; i < propertyNames.Length; i++)
{
propertyNames[i] = GetPropertyName(expressions[i]);
}
return propertyNames.Join();
}
I know it also can be done using reflection, but this one is tremendously fast or, I can say, equivalent to a lambda after first compilation. The very first iteration takes just an average of 10 milliseconds. So this is Expression Tree magic. Simple and fantastic (I think)!
我知道它也可以使用反射来完成,但是这个速度非常快,或者我可以说,在第一次编译后相当于一个 lambda。第一次迭代平均只需要 10 毫秒。所以这就是表达树魔法。简单而美妙(我认为)!