简体   繁体   中英

typeof() works, GetType() doesn't works when retrieving property

I am trying to retrieve a value of private property via reflection

// 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 !
    ...

Where is my mistake? I will need to use object to pass instance, because some of private properties will be declared in the A or B . And even hiding (with new ) Base properties sometimes.

Test is private to Base. It is not visible to the inherited A/B classes. You should make it protected if you want it visible to the inheriting class.

Or you can use GetType().BaseType if the inheritance tree is just one level.

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));

}

A inherits from Base , so you need to tell GetProperty to look for properties in the base class as well. Pass the FlattenHierarchy flag as well:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM