C# 在运行时检查属性类型,并为泛型lambda表达式参数T提供相同的类型

C# 在运行时检查属性类型,并为泛型lambda表达式参数T提供相同的类型,c#,.net,linq,generics,lambda,C#,.net,Linq,Generics,Lambda,我有一些代码片段,如下所示: 希望通过在运行时检查类型来解决此问题 PropertyInfo pi = type.GetProperty("propertyName"); var expression = new Object(); // this give me error after expression runs! // Want to resolve this conditation by checking the type at runtime. if (pi.Pr

我有一些代码片段,如下所示:

希望通过在运行时检查类型来解决此问题

PropertyInfo pi = type.GetProperty("propertyName");

var expression = new Object(); // this give me error after expression runs!

    // Want to resolve this conditation by checking the type at runtime.
    if (pi.PropertyType == typeof(DateTime))
            {
               // Want to pass the generic type parameter which has a same type created at runtime by identifying the property type.
                expression = BuildExpression<T, DateTime>(data, group.Member);
            }

private Func<T, V> BuildExpression<T, V>(IEnumerable<T> items, string propertyName)
    {
      Type type = typeof(T);
      PropertyInfo pi = type.GetProperty(propertyName);
      Type PropertyType = pi.DeclaringType;
      var parameter = Expression.Parameter(typeof(T), propertyName);
      var cast = Expression.TypeAs(parameter, pi.DeclaringType);
      var getterBody = Expression.Property(cast, pi);
      var exp = Expression.Lambda<Func<T, V>>(getterBody, parameter);
      return exp.Compile();
    }
PropertyInfo pi=type.GetProperty(“propertyName”);
变量表达式=新对象();//表达式运行后,这会给我错误!
//希望通过在运行时检查类型来解决此问题。
if(pi.PropertyType==typeof(DateTime))
{
//希望传递泛型类型参数,该参数具有通过标识属性类型在运行时创建的相同类型。
expression=BuildExpression(数据,group.Member);
}
私有Func构建表达式(IEnumerable项、字符串属性名称)
{
类型=类型(T);
PropertyInfo pi=type.GetProperty(propertyName);
类型PropertyType=pi.DeclaringType;
var参数=Expression.parameter(typeof(T),propertyName);
var cast=Expression.TypeAs(参数,pi.DeclaringType);
var getterBody=Expression.Property(cast,pi);
var exp=Expression.Lambda(getterBody,参数);
返回exp.Compile();
}
问题: 我必须在类型上写条件,我必须通过反射检查属性的类型,然后必须构建表达式

我想要什么: 我希望检查属性类型的运行时,并希望构建与属性类型相同的该类型的运行时泛型参数

基本上,我想删除类型检查中的
If
条件,我想要的是,代码应该
自动检测属性类型
,并在
泛型参数参数中传递相同的类型
,这样我就不必检查具有
If
条件的所有类型。如字符串、十进制、双精度等。


如果我想在运行时检查
属性
类型,并想创建与属性类型相同的
泛型参数类型
,请告诉我该解决方案。

有一个返回
Func
(对于对象
T
和成员类型
V
)的方法是有问题的,因为在运行时,你不能用它做任何有用的事情。在编译时不知道
t
V
的情况下,不能将其分配给键入的委托,使用
DynamicInvoke
也不是一个好主意。坦率地说,您最好构建一个
Func
,并在运行时处理
对象。反射和泛型不能很好地混合

private static Func<object, object> BuildExpression(
    Type type, string propertyName)
{
    var parameter = Expression.Parameter(typeof(object));
    var body = Expression.TypeAs(Expression.PropertyOrField(Expression.TypeAs(
        parameter, type), propertyName), typeof(object));
    return Expression.Lambda<Func<object, object>>(body, parameter).Compile();
}

那么,您的
BuildExpression
方法是什么?它能接受一个
Type
参数而不是
T
generic吗?Marc,它接受的是generic参数类型。我在问题中添加了相同的方法。您的
表达式
局部变量的类型是什么?这是我想知道的,因为我不确定如何初始化我的局部变量,因为在运行时进行不同类型的检查时,它会有所不同。。我已经把上面的代码贴在我的意见应该是这样的地方。但不知道如何处理这种情况。。。我已经用“var expression=new Object();”进行了初始化,但它在表达式运行后给了我错误!马克,谢谢你的信息。在使用了您的方法之后,我得到了的LamdaExpression。那很好。让我们假设,我想用‘integer’类型的lamda表达式来构建这个表达式。如何将方法的结果转换为“整型”表达式???@nunu将其作为“整型表达式”会导致巨大的问题,因为您不能拥有“整型表达式、字符串表达式、日期时间表达式或…”的变量-但是,您可以拥有“对象表达式”。你到底想做什么?如果它是一个整数表达式,您会如何使用它?我想在这里做的是,无论我从您的方法“BuildExpression”得到什么结果(Func),我都想在IEnumerable的“GroupBy”扩展方法中使用该结果Func。例如,var expResult=BuildExpression(typeof(T),“City”);var gropupedResult=myList.GroupBy(expResult);我该如何做到这一点呢?@nunu我不想一开始;但是,我可能会编写一个自定义的
GroupBy(这个IEnumerable,string memberName)
,基本上借用了这个自定义
OrderBy的代码回答:
var accessor = TypeAccessor.Create(type);
var obj = ...
var propVal = accessor[obj, propertyName];