【问题标题】:Accessing Type T property in the ParameterExpression type Dictionary<string,T>访问 ParameterExpression 类型 Dictionary<string,T> 中的 Type T 属性
【发布时间】:2017-01-27 10:41:16
【问题描述】:

我有用于数据过滤的表达式树代码,直到它被用于通用列表 List&lt;T&gt; 并且以下代码可以正常工作:

var parameterType = Expression.Parameter(typeof(T), "obj");
var memberExpression = Expression.Property(parameterType, "Name");

很容易创建如下二进制表达式并处理结果:

var constantExpression = Expression.Constant("Jack",typeof(string));

var finalExpression = Expression.Equal(memberExpression,constantExpression);

var resultFunc = Expression.Lambda<Func<T, bool>>(finalExpression, parameterType).Compile();

// Final Result
sourceList.Where(obj => resultFunc(obj));

这里NameType T 中的一个属性,因为Lambda 编译后的结果是Func&lt;T,bool&gt;,我曾经将其应用于Where 类型的Where 子句。现在底层系统已更改为在Dictionary&lt;string,T&gt; 上使用相同的代码,因此集合中的所有类型 T 值现在都具有关联的字符串键,并且类型 T 现在可以作为字典对象的值访问。另外我正在申请IQueryable,它采用表达式树,源端的最终lambda后编译将为Func&lt;KeyValuePair&lt;string,T&gt;,bool&gt;,因此无法在最终结果处理中应用该值。

以下是现在的代码修改:

var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");

以下代码失败,因为现在 Name 属性位于 KeyValuePair 的 Value 中,我们不能将其用作 Type T:

var memberExpression = Expression.Property(parameterType, "Name");

有什么可以让它发挥作用的指针,或者有什么建议可以让我朝着正确的方向前进吗?

【问题讨论】:

    标签: c# .net lambda expression-trees func


    【解决方案1】:

    您可以通过这种方式获取调用 ["name"] 项的表达式:

    var nameProperty= Expression.Call(parameterType, 
           typeof(IDictionary<string, T>).GetMethod("get_Item"), 
           Expression.Constant("Name")); 
    

    或作为:

    var nameProperty = Expression.Property(parameterType, "Item", 
                             new Expression[] { Expression.Constant("Name") });
    

    两者都是Item属性的调用

    编辑:要从KeyValuePair 获取值,您必须获取属性键,将其与“名称”和属性值进行比较,然后将其与值进行比较:

    var parameterType = Expression.Parameter(typeof(KeyValuePair<string,T>), "obj");
    
    var value = Expression.Property(parameterType, "Value" );
    var key = Expression.Property(parameterType, "Key");
    
    var  eq1 = Expression.Equal(key, Expression.Constant("Name"));
    var  eq2 = Expression.Equal(value, constantExpression);
    var and = Expression.And(eq1, eq2);
    var lambda = Expression.Lambda(and, parameterType);
    

    【讨论】:

    • 我的问题有误,请重新检查,我想现在提供 KeyValuePair 而不是 Dictionary,它是 KeyValue 对的集合我可以使用您建议的相同解决方案吗,我的理解是可以的
    • 我也没有办法使用 KeyValue 对的Value 属性来获取,而不是像使用 Item 数组那样使用索引器访问
    • 这个访问类型 T 的 Name 属性:Expression.Property(parameterType, "Value" ) 吗?,它是用于 Value 访问,它给出了整个对象
    • @MrinalKamboj 对不起,我先没明白,问题是什么,我更新了答案
    • 您可能错过的唯一一点是,以下代码 Expression.Property(parameterType, "Value") 将为我提供一个 Type T,作为其访问 KV 的 Value 属性,现在我需要进一步访问 Name 属性,所以我最需要的是:Expression.Property(value, "Name" ),要创建最终表达式,我正在对其进行测试。 Name 不是 KV 的密钥,如下代码所示:Expression.Equal(key, Expression.Constant("Name"))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2012-06-03
    相关资源
    最近更新 更多