C# MemberExpression中的ReflectedType

C# MemberExpression中的ReflectedType,c#,.net,linq-expressions,C#,.net,Linq Expressions,鉴于此代码: 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); } p

鉴于此代码:

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
{
}
static void Main(字符串[]args)
{
表达式测试=i=>i.Prop;
var body=(UnaryExpression)test.body;
Console.WriteLine(((MemberExpression)body.Operand.Member.ReflectedType);
}
公共类
{
公共int属性{get;私有集;}
}
公共类SomeDerivedClass:SomeClass
{
}
如果ReflectedType是表达式的参数类型,我希望它是SomeDerivedClass。但是它是SomeClass,如果我理解正确的话,它是声明类型


这是为什么?

属性
ReflectedType
检索用于获取此
成员信息实例的类型对象。如果此MemberInfo对象表示从基类继承的成员,则这可能不同于
DeclaringType
属性的值


这是因为表达式的计算结果为
Prop
,它是在
SomeClass
中定义的,而不是在
SomeDerivedClass
中定义的。请注意,
SomeDerivedClass
仅仅是
test
lambda参数的类型,因此它与其主体的类型无关,主体是一个
UnaryExpression
访问位于
SomeClass
中的属性


还可以尝试将
Prop
添加到
SomeDerivedClass
,您将得到预期的结果。

表达式树构建的确切细节在很大程度上尚未确定。唯一重要的是表达式树对应于用于构建表达式树的C#语法。在一个普通的C#表达式中,只有等价的
DeclaringType
,它被编码在IL中。该成员根本无法通过反射访问,因此没有<代码> ReflectedType <代码>要考虑。因为没有<代码> ReflectedType <代码>要考虑,所以两个不同的<代码> PrimeType < /Cord>对象对应于原始源代码。

因为一个潜在的原因,考虑这个有点邪恶的派生类:

public class SomeClass
{
    public int Prop { get; set; }
}

public class SomeDerivedClass : SomeClass
{
    public int get_Prop() { return 4; }
}
在这里,基类的
Prop
getter不会被重写,但是原始的
get\u Prop
属性编译器生成的getter函数只能通过基类使用。因此,
Prop
的唯一正确属性getter是
SomeClass.get\u Prop
SomeDerivedClass.get_Prop
不能使用,即使在静态已知为
SomeDerivedClass
的对象上访问
Prop


结合这一事实,C#编译器生成的代码在内部构建表达式树,通过获取属性getter方法,并要求运行时查找相应的
PropertyInfo
,获得适当的
PropertyInfo
对象,您已经得到了答案:属性getter方法只能从
SomeClass
可靠地获得,因此您也将从
SomeClass
获得
PropertyInfo
,您误解了这个问题。OP说,
ReflectedType
是基类型,而他希望它是后代类类型,我已经解释了为什么根据文档,反射类型是声明成员的类型
DeclaringType
总是声明成员的类型,这就是为什么它被称为
DeclaringType
。在OP的例子中,
DeclaringType
ReflectedType
都是
SomeClass
。谢谢你的回答,我误解了这个问题。只需运行代码,它们确实是相同的。您也可以使用
虚拟
基本属性来说明这一点。使用
override
关键字,您将获得
SomeClass
。但是,使用(丑陋)
new
关键字,您将获得
SomeDerivedClass
。如果基本属性是
virtual
,并且您
覆盖它,则该属性将不起作用。