一尘不染

Lambda表达式未返回预期的MemberInfo

c#

我遇到了一个我没有想到的问题。一个例子可能比一段更好地说明我的问题:

更新:跳到最后一个代码块,以获得更雄辩的代码示例。

public class A
{
  public string B { get; set; }
}

public class C : A { }

这是方法中的一些代码:

var a = typeof(C).GetMember("B")[0];
var b = typeof(A).GetMember("B")[0];

Expression<Func<C, string>> c = x => x.B;

var d = (c.Body as MemberExpression).Member;

以下是一些比较的结果:

a == b //false
a == d //false
b == d //true

前两个有点出乎意料。我知道即使B不是虚拟的,C仍可以使用thew new运算符定义一个具有相同名称的属性,但是在这种情况下我没有。

第二个对我来说真的是最令人惊讶的(也是我问题的核心)。即使将lambda的参数明确定义为C类型,它仍会返回该参数,就好像该属性是从基类访问的一样。

我正在寻找的是一种从lambda表达式获取MemberInfo的方法,就好像我对参数类型使用反射来获取MemberInfo一样。我的项目实质上将MemberInfos存储在各种字典中,并且它需要具有一些功能,在其中您可以通过提供lambda表达式来访问元素。

Danny Chen重新编写的代码示例

public class Base
{
    public string Name { get; set; }
}
public class Derived : Base { }

//in Main
var parentMember = typeof(Base).GetMember("Name")[0];
var childMember = typeof(Derived).GetMember("Name")[0];

Expression<Func<Base, string>> parentExp = x => x.Name;
var parentExpMember = (parentExp.Body as MemberExpression).Member;

Expression<Func<Derived, string>> childExp = x => x.Name;
var childExpMember = (childExp.Body as MemberExpression).Member;

parentMember == childMember  //false, good
parentMember == parentExpMember  //true, good
childMember == childExpMember   //false, why?

阅读 273

收藏
2020-05-19

共1个答案

一尘不染

取表达式(第一个)参数的类型,然后说

Expression<Func<C, string>> c = x => x.B; 
Type paramType = c.Parameters[0].Type;  // first parameter of expression
var d = paramType.GetMember((c.Body as MemberExpression).Member.Name)[0];
2020-05-19