create - lambda c#
Uso práctico de árboles de expresión (8)
Los árboles de expresión son una buena característica, pero ¿cuáles son sus usos prácticos? ¿Se pueden usar para algún tipo de generación de código o metaprogramación o algo así?
Acabo de crear una generic filter function
usando ExpressionTree
. Quiero share
con ustedes ...
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();
}
....... Sé que también se puede hacer usando Reflection
... pero este es tremendamente rápido o puedo decir equivalente a Lambda
después de la primera compilación ... La primera iteración es solo una lenta de 10 milisegundos. .. Así que esta es Expression Tree
magia del Expression Tree
. Simple y fantástico ... ¡¡¡Creo que ... !!!!!!!!
La implementación de proveedores de LINQ se realiza principalmente mediante el procesamiento de árboles de expresiones. También los estoy usando para eliminar cadenas literales de mi código:
Los uso para crear consultas dinámicas, ya sea para clasificar o filtrar los datos. Como ejemplo:
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));
Marc Gravell los ha utilizado con gran MiscUtil en MiscUtil para implementar operadores genéricos .
Originalmente por Jomo Fisher , Gustavo Guerra publicó una versión revisada del diccionario de cadenas estáticas .
Donde a través de Expression trees, una expresión dinámica que proporciona un diccionario realmente (léase: ridículamente).
La implementación crea un árbol de decisión dinámico que selecciona el valor actual de acuerdo con la longitud de la cadena de entrada, luego con la primera letra, luego con la segunda letra y así sucesivamente.
Esto finalmente se ejecuta mucho más rápido que el Diccionario equivalente.
Puede usarlos para crear su propio proveedor de linq para un sitio web como Google o Flickr o Amazon, su propio sitio web u otro proveedor de datos.
Usé el árbol de expresiones para construir un evaluador de expresiones matemáticas: construyendo el evaluador de expresiones con árboles de expresiones en C #
Como señala Jon, los uso para proporcionar operadores genéricos con .NET 3.5. También los uso (de nuevo en MiscUtil) para proporcionar acceso rápido a constructores no predeterminados (no puedes usar Delegate.CreateDelegate
con constructores, pero Expression
funciona bien).
Otros usos de árboles de expresiones creados manualmente:
Pero realmente, Expression es una forma muy versátil de escribir cualquier código dinámico. Mucho más simple que Reflection.Emit
, y para mi dinero, más simple de entender que CodeDOM. Y en .NET 4.0, tienes aún más opciones disponibles. Muestro los fundamentos de escribir código a través de Expression
en mi blog .