如何将expression式<Func <T,DateTime >>转换为expression式<Func <T,object >>
我一直在寻找,但我无法find如何从types投下
Expression<Func<T, DateTime>>
到types:
Expression<Func<T, object>>
所以我必须再次转向这个广阔的知识;)
你不能只在他们之间施放,因为他们不是同一种东西。 但是,您可以在expression式树中有效地添加转换:
using System; using System.Linq.Expressions; class Test { // This is the method you want, I think static Expression<Func<TInput,object>> AddBox<TInput, TOutput> (Expression<Func<TInput, TOutput>> expression) { // Add the boxing operation, but get a weakly typed expression Expression converted = Expression.Convert (expression.Body, typeof(object)); // Use Expression.Lambda to get back to strong typing return Expression.Lambda<Func<TInput,object>> (converted, expression.Parameters); } // Just a simple demo static void Main() { Expression<Func<string, DateTime>> x = text => DateTime.Now; var y = AddBox(x); object dt = y.Compile()("hi"); Console.WriteLine(dt); } }
Rob和Jon Skeet的答案有一个问题。
你得到像x => Convert(x.PropertyName)
这样的东西,但是经常为了ASP.NET MVC你想要一个像这样的expression式x => x.PropertyName
所以Expression.Convert
在某些情况下会“污染”expression式。
解:
public static class LambdaExpressionExtensions { public static Expression<Func<TInput, object>> ToUntypedPropertyExpression<TInput, TOutput> (this Expression<Func<TInput, TOutput>> expression) { var memberName = ((MemberExpression)expression.Body).Member.Name; var param = Expression.Parameter(typeof(TInput)); var field = Expression.Property(param, memberName); return Expression.Lambda<Func<TInput, object>>(field, param); } }
用法:
Expression<Func<T, DateTime>> expression = ...; Expression<Func<T, object>> expr = expression.ToUntypedPropertyExpression();
根据Jon的代码(谢谢btw),您可以进一步完善灵活性:
public static Expression<Func<TModel, TToProperty>> Cast<TModel, TFromProperty, TToProperty>(Expression<Func<TModel, TFromProperty>> expression) { Expression converted = Expression.Convert(expression.Body, typeof(TToProperty)); return Expression.Lambda<Func<TModel, TToProperty>>(converted, expression.Parameters); }
只需将TResult定义为对象并编译expression式,它适用于所有数据types;
Expression<Func<string, object>> dateExp = text => DateTime.Now; object dt = dateExp.Compile()("hi"); Console.WriteLine(dt);
在这里小提琴样品