Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

reflection

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.

like image 626
Sinatr Avatar asked Mar 07 '14 11:03

Sinatr


People also ask

What is the difference between GetType and typeof?

typeof keyword takes the Type itself as an argument and returns the underline Type of the argument whereas GetType() can only be invoked on the instance of the type.

How do I use GetType?

The GetType method is inherited by all types that derive from Object. This means that, in addition to using your own language's comparison keyword, you can use the GetType method to determine the type of a particular object, as the following example shows.

What is return type of GetType ()?

The gettype() function returns the type of a variable.


2 Answers

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

}
like image 200
podiluska Avatar answered Oct 13 '22 09:10

podiluska


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) 
like image 39
zmbq Avatar answered Oct 13 '22 09:10

zmbq