当我在抽象类中拥有此属性时:
public IList<Component> Components { get; private set; }
然后我打电话:
p.GetSetMethod(true)
p是指向我的属性的PropertyInfo对象,我得到null。
但是,如果我将属性设置器更改为protected,我可以通过反射看到它。为什么是这样?我似乎没有回忆起非抽象类的问题......
答案 0 :(得分:8)
我假设您在抽象类的派生类型的对象上调用它。该课程根本没有属性设定者。它只位于您的抽象基础上。这就是为什么它将它标记为protected
时的工作原理。获取属性设置器时,需要使用抽象类“Type
”。
答案 1 :(得分:6)
这是一个老线程,但我最近遇到了类似的问题,以上都没有为我工作。添加我的解决方案,因为它可能对其他人有用。
如前所述,如果属性的setter是private,则它不存在于继承的类中。对我有用的是使用DeclaringType
PropertyInfo
降低一级
因此使用setter检索属性的代码如下所示:
var propertyInfo = typeof(MyClass)
.GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance)
.DeclaringType
.GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance);
在这种情况下,propertyInfo
包含SetMethod
的值,因此您可以使用反射设置值。
答案 2 :(得分:3)
C#Interactive窗口中的一些简短实验表明,对于在类P
上声明的属性A
,以下工作正常:
var p = typeof(A).GetProperty("P").GetSetMethod(true)
但是只要您使用A
的子类尝试相同的操作,GetSetMethod
就不再解析私有set
访问者:
// class B : A {}
var p = typeof(B).GetProperty("P").GetSetMethod(true) // produces 'null'.
换句话说,当反射类型与属性的声明类型相同时,您尝试的只显示private
个访问器。
答案 3 :(得分:1)
诀窍是使用BindingFlags枚举来指定在获取PropertyInfo
对象时希望包含私有成员:
PropertyInfo p = obj.GetType().GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance);
答案 4 :(得分:0)
以@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);
我将公共和非公开添加到我的用例的绑定标志中(可能有点矫枉过正,我没有时间进一步追求它)
我正在设置一个从具有公共get和private set
的抽象基础继承的对象的实例再一次,归功于@piotrwolkowski
答案 5 :(得分:0)
以下实验为我揭开了这个问题。请注意,基类不必abstract
来重现问题。
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
}
}
我从中学到的并且发现令人惊讶的是,派生类型上的PropertyInfo
与基类型上的PropertyInfo
不同。怪异!