c# - 在运行时检查属性类型并将相同的类型赋予通用 lambda 表达式参数 T

标签 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.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();
    }

问题: 我必须在类型上写条件我必须通过反射检查属性的类型,然后必须构建表达式。

我想要的: 我想检查属性类型的运行时时间,并想构建与属性类型相同的类型的运行时通用参数。

基本上我想删除 If 条件 类型检查 我想要的是,代码应该自动检测属性类型 和在 Generic parameter argument 中传递相同的类型,这样我就不必使用 If 条件检查所有类型。比如 string, decimal, double etc..

能否请您告诉我该解决方案,因为我想在运行时检查 property 类型并想创建具有相同类型的 Generic parameter type因为属性(property)有。

最佳答案

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

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();
}

然而,在那个时候你可以,IMO,只要切换到像 FastMember 这样的库,并使用基于名称的访问:

var accessor = TypeAccessor.Create(type);
var obj = ...
var propVal = accessor[obj, propertyName];

关于c# - 在运行时检查属性类型并将相同的类型赋予通用 lambda 表达式参数 T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13249206/

相关文章:

javascript - 在 Angular 切换开关上停止传播

.net - Azure Graph .Net SDK 用户选择参数不区分大小写,但成员不区分大小写

c# - XML + LINQ 是否会在 C# 中为大量数据提供良好的性能?

c# - 找到 x 项后中止 linq 查询?

c# - 这个LINQ表达式的解释

c# - 由于大小写不同,WPF Combobox 在 ItemSource 中找不到 SelectedValue

c# - List<String> ByRef

c# - 如何将静态资源字符串传递给 UWP 中的 ConverterParameter

c# - Azure 应用服务 - 同步期间日期时间更改

.net - 如何在 .Net 中使用触控板滚动