使用反射调用属性的方法
我想做的是使用反射调用属性的方法。我有原始的控件(ComboBox)、属性的PropertyInfo(ComboBox.Items)和方法的名称(ComboBox.Items.Add)。我已尝试使用下面的代码来获取、更改、设置 - 但它不起作用,因为 Items
没有设置器。
PropertyInfo p = controlType.GetProperty(propertyName); // gets the property ('Items')
MethodInfo m = p.PropertyType.GetMethod(methodName); // gets the method ('Items.Add')
object o = p.GetValue(newControl, null); // gets the current 'Items'
m.Invoke(o, new object[] { newValue }); // invokes 'Add' which works
p.SetValue(newControl, o, null); // exception: 'Items' has no setter
有人有什么建议吗?
What I'm trying to do is call the method of a property, using Reflection. I have the original Control (a ComboBox), the PropertyInfo of the property (ComboBox.Items) and the name of the method (ComboBox.Items.Add). I've tried the code below to get, alter, set - but it doesn't work because Items
doesn't have a setter.
PropertyInfo p = controlType.GetProperty(propertyName); // gets the property ('Items')
MethodInfo m = p.PropertyType.GetMethod(methodName); // gets the method ('Items.Add')
object o = p.GetValue(newControl, null); // gets the current 'Items'
m.Invoke(o, new object[] { newValue }); // invokes 'Add' which works
p.SetValue(newControl, o, null); // exception: 'Items' has no setter
Does anyone have any advice?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
那很快...我将 Invoke 行更改为...
...并且它起作用了:P
That was quick... I changed the Invoke line to...
...and it worked :P
@acron,感谢您提供了一个很好的问题和答案。我想为未来的任何人扩展您的解决方案,以适应稍微不同的场景。
面对 ASP.NET 世界中的类似问题,我试图找到一种通用方法来加载 System.Web.UI.Webcontrols.DropDownList 或 System.Web.UI.HtmlControls .HtmlSelect 虽然这两个都具有“ListItemCollection”类型的“Items”属性,并具有相应的“Add”方法,但它们不共享公共接口(因为它们应该...嘿微软...),这样就可以使用强制转换。
您的解决方案未提供的额外挑战是 Add 方法的重载。
如果您的线路没有过载:
MethodInfo m = p.PropertyType.GetMethod(methodName);
工作得很好。但是,当重载 Add 方法时,会调用一个附加参数,以便运行时可以识别要调用哪个重载。
MethodInfo methInfo = propInfo.PropertyType.GetMethod("Add", new Type[] { typeof(ListItem) });
@acron, Thanks for providing a great question and answer. I want to extend your solution for a slightly different scenario for anyone looking in the future.
Facing a similar problem in the ASP.NET world I was trying to find a common way to load either a System.Web.UI.Webcontrols.DropDownList OR a System.Web.UI.HtmlControls.HtmlSelect While both of these have an "Items" property of type "ListItemCollection", with a corresponding "Add" method, they do not share a common interface (as they SHOULD... hey Microsoft...) so that casting can be used.
The additional challenge that your solution didn't provide for is the overloading of the Add method.
Without the overloads your line:
MethodInfo m = p.PropertyType.GetMethod(methodName);
works just fine. But, when the Add method is overloaded an additional parameter is called for so that the runtime can identify which overload to invoke.
MethodInfo methInfo = propInfo.PropertyType.GetMethod("Add", new Type[] { typeof(ListItem) });
您收到的错误表明相关属性是只读的。没有定义 set 方法。如果没有设置器,您将无法设置属性的值。
回复并附上房产名称或更多背景信息,我们也许能够为您提供更好的答案或替代方案。
The error that you are getting indicates that the property in question is read only. There is no set method defined. You will not be able to set the value for the property without a setter.
Post back with the name of the property or more context and we may be able to give you a better answer or an alternative.