Отражение и настройка свойства? - PullRequest
1 голос
/ 29 апреля 2011

Итак, у меня есть объектный класс, который унаследован от другого класса.Однако всякий раз, когда я пытаюсь установить дочерний класс с помощью метода 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 ]

2 голосов
/ 29 апреля 2011

Вот как я это делаю, используя 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 голос
/ 29 апреля 2011

Если вы попробуете этот небольшой фрагмент кода в том месте, где вы это делаете.на другой тип ...

Type t = typeof(Person);

и, вероятно,

(Person)this

при вызове?потому что вызов принимает объект, который включает тип ...

РЕДАКТИРОВАТЬ: я не понял, что вы делаете это со свойствами ... вы должны использовать Setvalue intad вызывания:)

Если вы действительно хотите вызывать его следующим образом:

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

Метод набора свойств в .NET на данный момент "set_PropertyName" ... Вы не видите этого в коде, но компиляция компилирует свойствадва метода, один для set и один для get (при условии, что он не только для чтения, тогда вы получите только Get)

0 голосов
/ 29 апреля 2011

Вместо использования InvokeMember, поскольку вы устанавливаете значение свойства, как насчет использования SetValue?

property.SetValue(this, fields[x], null);
0 голосов
/ 29 апреля 2011

Почему вы не вызываете SetValue напрямую?

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

Вы можете установить свойство через объект PropertyInfo.

...