【问题标题】:C# MemberExpression for a specific dictionary item特定字典项的 C# MemberExpression
【发布时间】:2019-07-02 22:21:22
【问题描述】:

我正在尝试使用 Expression.MakeBinary 动态生成二进制表达式:

public static BinaryExpression MakeBinary(
    ExpressionType binaryType,
    Expression left,
    Expression right
)

类“Foo”的属性“Bar”的一个简单示例是:

var param = Expression.Parameter(typeof(Foo));
var left = MemberExpression.Property(param, "Bar");
var propertyType = typeof(Foo).GetProperty("Bar").PropertyType;
var right = Expression.Constant(Convert.ChangeType("newValue", propertyType ));
var expression = Expression.MakeBinary(ExpressionType.Equal, left, right);

我的目标是能够做与上述相同的事情,但不是将“Bar”属性与“newValue”进行比较,在我的情况下,“Bar”是一个字典,我想比较该字典的特定条目与“新价值”。我想要达到的效果是这样的(但是这段代码是无效的):

var param = Expression.Parameter(typeof(Foo));
var left = MemberExpression.Property(param, "Bar[\"entryName\"]");

我想我正在尝试做的事情是可能的,但我似乎找不到要使用的正确语法/类/方法。显然,上面的代码会返回错误,因为 Bar["entryName"] 不是属性。但是,如何根据给定类型的字典中的特定条目构建表达式?

它的高级应用是能够应用规则,使用字段/运算符/compareValue 作为参数,但能够指示该字段的“路径”(取决于类,有时它会是一个普通的属性,或者在这里询问,字典中的条目等)。

谢谢

【问题讨论】:

  • 我搜索过,但没有意识到这会为我的问题提供答案。现在有了 René 的回答,我发现我可以重用该答案的一些组成部分并将其应用于我的案例。谢谢你指出这一点。代码示例越多越好:)。
  • 没关系。 Rene 给出了很好的答案,我很高兴地投了赞成票 :) 但我知道,这个问题已经被问过很多次了,所以我指出了一个重复的问题。我知道,很难搜索,如果您不确切知道您在寻找什么,我并不怀疑,您还没有直接找到答案

标签: c#


【解决方案1】:

你可以使用Expression.MakeIndex():

var param = Expression.Parameter(typeof(Foo));
var bar = MemberExpression.Property(param, "Bar");

Type dictionaryType = typeof(Foo).GetProperty("Bar").PropertyType;
PropertyInfo indexerProp = dictionaryType.GetProperty("Item");
var dictKeyConstant = Expression.Constant("entryName");
var dictAccess = Expression.MakeIndex(bar, indexerProp, new[] {dictKeyConstant});

var propertyType = indexerProp.PropertyType;
var right = Expression.Constant(Convert.ChangeType("newValue", propertyType ));
var expression = Expression.MakeBinary(ExpressionType.Equal, dictAccess, right);    

索引器的属性名称始终为“Item”。 dictKeyConstant 应该是字典键的表达式。

【讨论】:

  • 名称“Item”对于Dictionary<T,U> 是正确的,但它可以在自定义类中重命名,并应用适当的IndexerNameAttribute。如果在其他地方应用它,请注意一些事情。值得注意的是,VB 的非默认索引属性也会有不同的处理方式。
  • 非常感谢 René,这正是我想要的。这是我在 C# 表达式中的第一次跳跃,与我通常做的编程类型非常不同。非常有趣和灵活,再次感谢,现在我更好地理解了我们必须对这些表达式采取的方法类型,一开始我有点迷茫,因为它是一个比典型 LINQ 更高的抽象级别,我真的不知道如何与基础知识之外的上下文中的对象进行交互。
  • @roboris 不客气。别担心,我的脑子也还在疼。
猜你喜欢
  • 1970-01-01
  • 2016-11-06
  • 1970-01-01
  • 2018-08-30
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多