C# 如何将 Expression<Func<T, DateTime>> 转换为 Expression<Func<T, object>>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/729295/
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
How to cast Expression<Func<T, DateTime>> to Expression<Func<T, object>>
提问by antonioh
I've been searching but I can't find how to cast from the type
我一直在搜索,但我找不到如何从类型转换
Expression<Func<T, DateTime>>
to the type:
到类型:
Expression<Func<T, object>>
So I must turn again to the SO vast knowledge ;)
所以我必须再次求助于如此广泛的知识;)
采纳答案by Jon Skeet
You can't just cast between them, as they're not the same kind of thing. However, you can effectively add a conversion within the expression tree:
你不能只是在它们之间进行转换,因为它们不是同一种东西。但是,您可以在表达式树中有效地添加转换:
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);
}
}
回答by Rob
Based on the code from Jon (thanks btw) you can take it one step further for complete flexibility:
基于 Jon 的代码(感谢顺便说一句),您可以更进一步,以获得完全的灵活性:
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);
}
回答by Rookian
The answers from Roband Jon Skeethave one problem.
Rob和Jon Skeet的回答有一个问题。
You get something like x => Convert(x.PropertyName)
, but often for instance for ASP.NET MVCyou want an expression like this x => x.PropertyName
你会得到类似的东西x => Convert(x.PropertyName)
,但通常例如对于ASP.NET MVC你想要这样的表达式x => x.PropertyName
So Expression.Convert
is "polluting"the expression for some cases.
所以Expression.Convert
是“污染”的一些情况表达。
Solution:
解决方案:
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);
}
}
Usage:
用法:
Expression<Func<T, DateTime>> expression = ...;
Expression<Func<T, object>> expr = expression.ToUntypedPropertyExpression();
回答by Laz Ziya
Just define the out TResult as object and compile the expression, it works for all data types;
只需将 out TResult 定义为对象并编译表达式,它适用于所有数据类型;
Expression<Func<string, object>> dateExp = text => DateTime.Now;
object dt = dateExp.Compile()("hi");
Console.WriteLine(dt);