如何将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); } } 

RobJon 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); 

在这里小提琴样品