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
,并且您覆盖它,则该属性将不起作用。