鉴于此代码:
static void Main(string[] args)
{
Expression<Func<SomeDerivedClass, object>> test = i => i.Prop;
var body = (UnaryExpression) test.Body;
Console.WriteLine(((MemberExpression) body.Operand).Member.ReflectedType);
}
public class SomeClass
{
public int Prop { get; private set; }
}
public class SomeDerivedClass : SomeClass
{
}
我希望ReflectedType为SomeDerivedClass,因为它是表达式的参数类型。但它是SomeClass,如果我理解正确的话 - 声明类型。
为什么?
答案 0 :(得分:4)
表达树如何构建的确切细节很大程度上未指定。唯一重要的是表达式树对应于用于构建表达式树的C#语法。在普通的C#表达式中,只有DeclaringType
的等价物,它在IL中编码。该成员根本没有通过反思进行访问,因此没有ReflectedType
可以考虑。由于没有ReflectedType
要考虑,因此两个不同的PropertyInfo
对象与原始源代码的对应度相同。
为了一个可能的原因,请考虑这个有点邪恶的派生类:
public class SomeClass
{
public int Prop { get; set; }
}
public class SomeDerivedClass : SomeClass
{
public int get_Prop() { return 4; }
}
这里,基类的Prop
getter 不被覆盖,但是原始get_Prop
属性编译器生成的getter函数只能通过基类使用。因此,Prop
唯一正确的属性getter是SomeClass.get_Prop
。即使在静态已知为SomeDerivedClass.get_Prop
的对象上访问Prop
,也不得使用SomeDerivedClass
。
将此与内部事实相结合,构建表达式树的C#编译器生成的代码通过获取属性getter方法获取相应的PropertyInfo
对象,并要求运行时查找相应的{{1}你有答案:只能从PropertyInfo
可靠地获取属性getter方法,因此你也可以从SomeClass
获得PropertyInfo
。
答案 1 :(得分:1)
这是因为表达式的评估结果为Prop
,SomeClass
而不是SomeDerivedClass
。请注意,SomeDerivedClass
仅仅是test
lambda参数的类型,因此它与其正文的类型无关,即UnaryExpression
访问{{1}中的属性}}。
尝试将SomeClass
添加到Prop
,您将获得预期的结果。
答案 2 :(得分:-1)
ReflectedType
属性检索用于获取此MemberInfo
实例的Type对象。如果此MemberInfo对象表示从基类继承的成员,则此值可能与DeclaringType
属性的值不同。
http://msdn.microsoft.com/en-us/library/system.reflection.memberinfo.reflectedtype.aspx