Reflection cannot find private setter by property of abstract class

When I have this property in an abstract class:

public IList<Component> Components { get; private set; } 

Then when I call:

 p.GetSetMethod(true) 

when p is a PropertyInfo object pointing to my property, I get null.

However, if I change the setter property to protected, I see it through reflection. Why is this? I don't seem to remember that this problem occurs with non-abstract classes ...

+8
reflection c #
source share
6 answers

I assume that you are calling this on an object from a derived type of your abstract class. There is no property definition tool in this class. It is located only at your abstract base. This is why it works when you mark it as protected . Instead, you should use your abstract Type class when you get the setter property.

+6
source share

This is an old thread, but I have encountered a similar problem recently, and none of the above worked for me. Adding my solution as it may be useful to others.

As already mentioned, if a property of a property is private, it does not exist in the inherited class. For me it worked at the same level below using the DeclaringType PropertyInfo

Thus, the code for retrieving the property with the installer will look like this:

 var propertyInfo = typeof(MyClass) .GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance) .DeclaringType .GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance); 

In this case, PropertyInfo contains the value for SetMethod , so you can set the value using reflection.

+5
source share

Some brief experiments in the C # interactive window show that for property P declared in class A , the following works just fine:

 var p = typeof(A).GetProperty("P").GetSetMethod(true) 

But as soon as you try to do the same thing with subclass A , GetSetMethod no longer allows private set accessor:

 // class B : A {} var p = typeof(B).GetProperty("P").GetSetMethod(true) // produces 'null'. 

In other words, you were apparently trying to work only for private accessors when the reflected type matches the type of the property declaration.

+3
source share

The trick is to use the BindingFlags enumeration to indicate that you want private members to be included when the PropertyInfo object is received

 PropertyInfo p = obj.GetType().GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance); 
+1
source share

Building on work @piotrwolkowski

 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; var propertyInfo = typeof(MyClass).GetProperty("Components", flags); // only go to the declaring type if you need to if (!propertyInfo.CanWrite) propertyInfo = propertyInfo.DeclaringType.GetProperty("Components", flags); 

I have added both public and non-public anchor flags for my use case (this may be redundant and I don’t have time to continue it)

I installed an instance of an object inherited from an abstract base using public get and private set

Again all loans @piotrwolkowski

0
source share

The following experiments uncovered this problem for me. Note that the base class does not have to be abstract in order to reproduce the problem.

 public class Base { public string Something { get; private set; } } public class Derived : Base { } public class MiscTest { static void Main( string[] args ) { var property1 = typeof( Derived ).GetProperty( "Something" ); var setter1 = property1.SetMethod; //null var property2 = typeof( Base ).GetProperty( "Something" ); var setter2 = property2.SetMethod; //non-null bool test1 = property1 == property2; //false bool test2 = property1.DeclaringType == property2.DeclaringType; //true var solution = property1.DeclaringType.GetProperty( property1.Name ); var setter3 = solution.SetMethod; //non-null bool test3 = solution == property1; //false bool test4 = solution == property2; //true bool test5 = setter3 == setter2; //true } } 

What I learned from this and found surprising is that PropertyInfo for a derived type is a different instance than PropertyInfo for a base type. Weird!

0
source share

All Articles