Reflection and Setting Property?
So, I have a object class that is inherited from another class. However, whenever I try to set the child class with the InvokeMember method using reflection, it says that Method/Member doesn't exist. Am I 开发者_StackOverflow中文版missing something?
namespace Group {
public class Person {
public Guid PersonId { get; set; }
public string FirstName { get; set; }
public void Load(NameValueCollection fields) {
Type classType = this.GetType();
PropertyInfo[] properties = classType.GetProperties();
foreach(PropertyInfo property in properties)
{
for(int x = 0; x < fields.Count; x++)
{
if (fields.Keys[x] != property.Name) continue;
classType.InvokeMember(property.Name, BindingFlags.Instance | BindingFlags.SetProperty, Type.DefaultBinder, this, new object[] { fields[x] });
break;
}
}
}
}
namespace Group {
public class VIPPerson : Person { }
}
The following code calls the above class:
function someMethod() {
NameValueCollection collection = new NameValueCollection();
collection.Add("FirstName", "Mark");
VIPPerson person = new VIPPerson();
person.Load(collection);
}
Any help why the InvokeMember is throwing an error that says the property doesn't exist?
Here's how I do it using SetValue reading the value out of an xml file.
//--- Get Object Properties
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(targetComponent);
foreach (var xmlProperty in propertiesFromXML)
{
var propertyName = xmlProperty.Name.ToString();
var propertyDescriptor = props[propertyName];
if (propertyDescriptor == null)
{
// Property does not exist, create one anyways?
}
else
{
propertyDescriptor.SetValue(targetComponent, Convert.ChangeType(xmlProperty.Value, propertyDescriptor.PropertyType));
}
}
If you try this small snippet of code in the place where you do this.gettype()
you will understand what is going on:
Type t = this.GetType();
while (t.Name != typeof(Object).Name) {
Console.WriteLine(t.Name);
t = t.BaseType;
}
Console.WriteLine(t.Name);
Basically you are invoking something on a different type...
Type t = typeof(Person);
and probably
(Person)this
when invoking? because the invoke takes an object that boxes the type...
EDIT: I didnt catch that you are doing this with properties... you should use the Setvalue insetad of invoking :)
If you really wish to invoke it like this use:
classType.InvokeMember(property.GetSetMethod().Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, Type.DefaultBinder, (Person)this, new object[] { fields[x] });
The property set method in .NET is for now "set_PropertyName"... You don't see this in code, but compilation compiles properties in two methods, one for set and one for get (assuming it is not readonly, then you get only the Get)
Why arent you calling SetValue directly?
property.SetValue(this, fields[x], null);
You can set the property via the PropertyInfo object.
Instead of using InvokeMember
, since you're setting the property value, how about using SetValue?
property.SetValue(this, fields[x], null);
精彩评论