typeof()有效,GetType()在检索属性时不起作用

时间:2014-03-07 11:25:08

标签: c# reflection

我正在尝试通过反射

检索private属性的值
// definition
public class Base
{
    private bool Test { get { return true; } }
}
public class A: Base {}
public class B: Base {}

// now
object obj = new A(); // or new B()

// works
var test1 = typeof(Base).GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic);
if(test1 != null) // it's not null
    if((bool)test1.GetValue(obj, null)) // it's true
        ...

// doesn't works!
var test2 = obj.GetType().GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic);
if(test2 != null) // is null !
    ...

我的错误在哪里?我需要使用object来传递实例,因为某些private属性将在AB中声明。甚至隐藏(有newBase属性。

2 个答案:

答案 0 :(得分:8)

测试对Base是私有的。它对继承的A / B类不可见。如果您希望它对继承类可见,则应将其设为protected

如果继承树只是一个级别,您可以使用GetType().BaseType

public class Base
{
    private bool Test { get { return true; } }
    protected bool Test2 { get { return true; } }
}
public class A : Base { }
public class B : Base { }

[TestMethod]
public void _Test()
{
    object obj = new A(); // or new B()         

    Assert.IsNotNull(typeof(Base).GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic));
    Assert.IsNotNull(typeof(Base).GetProperty("Test2", BindingFlags.Instance | BindingFlags.NonPublic));

    Assert.IsNull(typeof(A).GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic));
    Assert.IsNotNull(typeof(A).GetProperty("Test2", BindingFlags.Instance | BindingFlags.NonPublic));

    Assert.IsNull(typeof(A).GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy));
    Assert.IsNotNull(typeof(A).GetProperty("Test2", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy));

    Assert.IsNull(obj.GetType().GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic));
    Assert.IsNotNull(obj.GetType().GetProperty("Test2", BindingFlags.Instance | BindingFlags.NonPublic));

    Assert.IsNotNull(obj.GetType().BaseType.GetProperty("Test", BindingFlags.Instance | BindingFlags.NonPublic));
    Assert.IsNotNull(obj.GetType().BaseType.GetProperty("Test2", BindingFlags.Instance | BindingFlags.NonPublic));

}

答案 1 :(得分:1)

A继承自Base,因此您需要告诉GetProperty在基类中查找属性。也传递FlattenHierarchy标志:

GetProperty("Test", BindingFlags.Instance 
      | BindingFlags.NonPublic 
      | BindingFlags.FlattenHeirarchy)