使用Reflection调用属性的方法

我要做的是使用Reflection调用属性的方法。 我有原始的Control(一个ComboBox),属性的PropertyInfo(ComboBox.Items)和方法的名称(ComboBox.Items.Add)。 我已经尝试了下面的代码来获取,更改,设置但它不起作用,因为Items没有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 

有人有建议吗?

谢谢

那很快……我把Invoke线改为……

 m.Invoke(p.GetValue(newControl, null), new object[] { newValue }); 

……它奏效了:P

@acron,感谢您提供了一个很棒的问题和答案。 我想扩展您的解决方案,为将来的任何人提供稍微不同的方案。

面对ASP.NET世界中的类似问题,我试图找到一种常见的方法来加载System.Web.UI.Webcontrols.DropDownListSystem.Web.UI.HtmlControls.HtmlSelect,而这两者都有一个“项目” “类型为”ListItemCollection“的属性,带有相应的”添加“方法,它们不共享一个公共接口( 因为它们应该……嘿微软…… )以便可以使用转换。

您的解决方案未提供的额外挑战是Add方法的重载。

没有重载你的行: MethodInfo m = p.PropertyType.GetMethod(methodName); 工作得很好。 但是,当重载Add方法时,会调用另一个参数,以便运行时可以识别要调用的重载。

MethodInfo methInfo = propInfo.PropertyType.GetMethod("Add", new Type[] { typeof(ListItem) });

您收到的错误表明相关属性是只读的。 没有定义set方法。 如果没有setter,您将无法设置属性的值。

回复财产名称或更多背景,我们可以为您提供更好的答案或替代方案。