Des arbres d'Expression sont une fonctionnalité intéressante, mais quelles sont ses utilisations pratiques? Peuvent-ils être utilisés pour une sorte de génération de code ou de la métaprogrammation ou quelque chose du genre?
Réponses
Trop de publicités?Comme Jon notes, je les utilise pour fournir les opérateurs génériques .NET 3.5. J'utilise également (à nouveau dans MiscUtil) pour permettre un accès rapide à des non-constructeurs par défaut (vous ne pouvez pas utiliser Delegate.CreateDelegate
avec des constructeurs, mais Expression
fonctionne très bien).
D'autres utilisations de créer manuellement des arbres d'expression:
Mais vraiment, l'Expression est une manière très polyvalente d'écrire aucun code dynamique. Beaucoup plus simple que Reflection.Emit
, et pour mon argent, plus simple à comprendre que CodeDOM. Et dans les .NET 4.0, vous avez encore plus d'options disponibles. Je montre les fondamentaux de l'écriture de code via Expression
sur mon blog.
Marc Gravel a utilisé à bon escient, dans MiscUtil pour mettre en œuvre les opérateurs génériques.
Je viens de créer un generic filter function
l'aide ExpressionTree
.. je veux share
avec vous les gars...
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();
}
....... Je sais qu'il peut aussi être fait en utilisant Reflection
... mais c'est formidable, rapide ou je peux dire equvalant d' Lambda
après la première compilation ... Et seulement une moyenne de 10 ms lent sur la première compilation ... c'est - Expression Tree
de la magie et de simplicité et faite de....Je pense que ...!!!!!!!!
- Je les utiliser pour créer des requêtes dynamiques, que ce soit pour des opérations de tri ou de filtrage des données. À titre d'exemple:
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));