reflection在抽象类的属性上找不到私有的setter
当我在抽象类中有这个属性时:
public IList Components { get; private set; }
然后当我打电话:
p.GetSetMethod(true)
如果p是一个指向我的属性的PropertyInfo对象,我得到null。
但是,如果我将属性setter更改为protected,我可以通过reflection看到它。 为什么是这样? 我似乎没有回忆起非抽象类的这个问题……
我假设您在抽象类的派生类型的对象上调用它。 该课程根本没有属性设定者。 它只位于您的抽象基础上。 这就是为什么它在您将其标记为protected
。 获取属性设置器时,需要使用抽象类’ Type
。
这是一个老线程,但我最近遇到了类似的问题,以上都没有为我工作。 添加我的解决方案,因为它可能对其他人有用。
如前所述,如果属性的setter是私有的,则它在inheritance的类中不存在。 对我来说DeclaringType
的是使用PropertyInfo
DeclaringType
降低一级
因此,使用setter检索属性的代码如下所示:
var propertyInfo = typeof(MyClass) .GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance) .DeclaringType .GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance);
在这种情况下, propertyInfo
包含SetMethod
的值,因此您可以使用reflection设置值。
C#Interactive窗口中的一些简短实验表明,对于在A
类上声明的属性P
,以下工作正常:
var p = typeof(A).GetProperty("P").GetSetMethod(true)
但是只要你用A
的子类尝试相同的东西, GetSetMethod
就不再解析私有set
访问器:
// class B : A {} var p = typeof(B).GetProperty("P").GetSetMethod(true) // produces 'null'.
换句话说,当reflection类型与属性的声明类型相同时,您试图显然只适用于private
访问器。
诀窍是使用BindingFlags枚举来指定在获取PropertyInfo
对象时希望包含私有成员:
PropertyInfo p = obj.GetType().GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance);
建立@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);
我将公共和非公共添加到我的用例的绑定标志(它可能是矫枉过正的,我没有时间进一步追求它)
我正在设置一个对象的实例,该对象inheritance自具有公共get和private set的抽象基础
再一次,归功于@piotrwolkowski
以下实验为我揭开了这个问题。 请注意,基类不必是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
不同的实例。 奇怪的!
- Control.invoke和父控件
- .Net AssemblyName.version构建与修订
- 如何使用Entity Framework以DataGridView可编辑和上下文跟踪更改的方式过滤数据?
- 什么是java的System.getProperty(“user.dir”)的.NET等价物?
- 是否可以在除C#之外的其他.NET语言中使用async-await?
- 如何加密sql server中的数据并在.net应用程序中解密它
- C#客户端如何调用wsdl文件
- 如何获取图像的一部分并将其用作单独的图像?
- Visual Studio 2010无法打开Visual Studio 2012修改的2010解决方案