反思和设定财产?

时间:2011-04-28 20:30:17

标签: c# reflection invoke

所以,我有一个从另一个类继承的对象类。但是,每当我尝试使用反射设置具有InvokeMember方法的子类时,它表示Method / Member不存在。我错过了什么吗?

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 { }
}

以下代码调用上述类:

function someMethod() {
    NameValueCollection collection = new NameValueCollection();
    collection.Add("FirstName", "Mark");

    VIPPerson person = new VIPPerson();
    person.Load(collection);
}

为什么InvokeMember抛出一个说明该属性不存在的错误的任何帮助?

4 个答案:

答案 0 :(得分:2)

以下是我使用SetValue读取xml文件中的值的方法。

        //--- 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));
            }

        }

答案 1 :(得分:1)

如果您在执行此操作的位置尝试此小代码段.gettype()

你会明白发生了什么:

        Type t = this.GetType();

        while (t.Name != typeof(Object).Name) {
            Console.WriteLine(t.Name);
            t = t.BaseType;
        }
        Console.WriteLine(t.Name);

基本上你在调用不同类型的东西......

Type t = typeof(Person);

可能

(Person)this

何时调用?因为调用采用一个对象来装入类型...

编辑:我没有意识到你正在使用属性这样做...你应该使用Setvalue insetad of invoking:)

如果您真的希望像这样使用它来调用它:

classType.InvokeMember(property.GetSetMethod().Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, Type.DefaultBinder, (Person)this, new object[] { fields[x] });

.NET中的属性集方法现在是“set_PropertyName”... 你没有在代码中看到这一点,但是编译在两个方法中编译属性,一个用于set,一个用于get(假设它不是readonly,那么你只得到Get)

答案 2 :(得分:0)

为什么你不直接调用SetValue?

property.SetValue(this, fields[x], null);

您可以通过PropertyInfo对象设置属性。

答案 3 :(得分:0)

而不是使用InvokeMember,因为您正在设置属性值,使用SetValue怎么样?

property.SetValue(this, fields[x], null);