【问题标题】:Creating expression tree for accessing a Generic type's property创建表达式树以访问通用类型的属性
【发布时间】:2013-01-24 11:45:06
【问题描述】:

我需要编写一个泛型方法,它采用泛型类型的实例和字符串格式的属性名称并返回一个表达式树

我需要转换一个简单的 lambda 表达式

a => a.SomePropertyName

其中a 是泛型类型,它将有一个属性,名称为SomePropertyName

我知道我们可以使用下面的反射代码来获取属性信息

System.Reflection.PropertyInfo propInfo = a.GetType().GetProperty("SomePropertyName");

这可能很简单,但是我对表达式树不太熟悉,如果有类似的问题,请链接并关闭它

【问题讨论】:

    标签: c# linq generics expression-trees


    【解决方案1】:

    假设事先不知道参数类型和返回类型,你可能不得不使用一些object,但基本上这只是:

    var p = Expression.Parameter(typeof(object));
    var expr = Expression.Lambda<Func<object, object>>(
        Expression.Convert(
            Expression.PropertyOrField(
                 Expression.Convert(p, a.GetType()), propName), typeof(object)), p);
    

    如果输入和输出类型已知,您可以调整Func&lt;,&gt; 参数,也可以删除Expression.Convert。在极端情况下,您可以在不知道 lambda 的 签名 的情况下获得一个 lambda ,通过:

    var p = Expression.Parameter(a.GetType());
    var expr = Expression.Lambda(Expression.PropertyOrField(p, propName), p);
    

    【讨论】:

    • 我们不能通过反射将类型传递给 Func 以获取 a 的类型和属性 SomePropertyName 吗?
    • @VamsiKrishna 第二个示例有 lambda 代码为您找出所有类型,但是:如果您使用完整的通用版本,您需要知道属性类型 静态 .因此我在第一个示例中使用了object,因为至少这将始终有效。如果你有一个使用TArgTResult 的通用方法,那么你当然可以构建一个Expression&lt;Func&lt;TArg,TResult&gt;&gt;
    【解决方案2】:

    你可以用这个:

    var p = Expression.Parameter(a.GetType(), "x");
    var body = Expression.Property(p, "SomePropertyName");
    
    Expression.Lambda(body, p);
    

    【讨论】:

    • 第一行中的“x”是什么?
    • @VamsiKrishna 只是参数的名称。在您的a =&gt; a.SomePropertyName 示例中,它是a
    • 正如 Marc 所说,它是参数的名称。它实际上可以省略,这里没有必要指定它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多