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?
Thanks
To set property values via Reflection, you must use the Type. GetProperty() method, then invoke the PropertyInfo. SetValue() method. The default overload that we used accepts the object in which to set the property value, the value itself, and an object array, which in our example is null.
Reflection provides objects (of type Type) that describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties.
To invoke a static method using its MethodInfo object, pass null for obj . If this method overload is used to invoke an instance constructor, the object supplied for obj is reinitialized; that is, all instance initializers are executed. The return value is null .
That was quick... I changed the Invoke line to...
m.Invoke(p.GetValue(newControl, null), new object[] { newValue });
...and it worked :P
@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) });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With