Ошибка «Метод набора свойств не найден» во время отражения - PullRequest
27 голосов
/ 20 февраля 2012

Я пытаюсь обдумать некоторые свойства класса и установить их программно, но похоже, что один из моих фильтров PropertyInfo не работает:

//Get all public or private non-static properties declared in this class (no inherited properties) - that have a getter and setter.
PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.SetProperty );

Я получаю сообщение об ошибке

pi.SetValue(this, valueFromData, null);

Поскольку у свойства есть только метод get{}, метод set{} отсутствует.

Мой вопрос: почему это свойство не было отфильтровано из реквизита? Я думал, что это было целью BindingFlags.SetProperty.

Свойство не фильтруется:

    public String CollTypeDescription
    {
        get { return _CollTypeDescription; }
    }

Обратите внимание, что я хочу отфильтровать свойства, которые не будут работать раньше времени, потому что я перечисляю их все сразу. Я не хочу использовать pi.GetSetMethod() после факта, чтобы определить, могу ли я использовать сеттер.

Ответы [ 3 ]

63 голосов
/ 20 февраля 2012

Из документации:

BindingFlags.SetProperty

Указывает, что значение указанного свойства должно быть установлено. За Свойства COM, указание этого флага привязки эквивалентно указание PutDispProperty и PutRefDispProperty.

BindingFlags.SetProperty и BindingFlags.GetProperty не фильтруют свойства, в которых отсутствуют сеттеры или геттеры соответственно.

Чтобы проверить, можно ли установить свойство, используйте свойство CanWrite.

if (pi.CanWrite)
    pi.SetValue(this, valueFromData, null);
2 голосов
/ 20 февраля 2012

Спасибо Кену за информацию.Похоже, это лучшее решение, которое я могу получить, чтобы отфильтровать их, протестировав GetSetMethod (true) в фильтре LINQ:

// Get all public or private non-static properties declared in this class
// (e.g. excluding inherited properties) that have a getter and setter.
PropertyInfo[] props = this.GetType()
    .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance |
                   BindingFlags.Public | BindingFlags.NonPublic)
    .Where(p => p.GetGetMethod(true) != null && p.GetSetMethod(true) != null)
    .ToArray();

В качестве альтернативы, используя CanRead и CanWrite:

PropertyInfo[] props = this.GetType()
    .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance |
                   BindingFlags.Public | BindingFlags.NonPublic)
    .Where(p => p.CanRead && p.CanWrite)
    .ToArray();

Мне неясно, дадут ли эти разные подходы разные результаты для разных уровней защиты методов get / set.

0 голосов
/ 20 февраля 2012

Я понимаю метод GetProperties (), поэтому он возвращает каждое свойство, имеющее BindingFlags.GetProperty или BindingFlags.SetProperty.
Поэтому, если вы хотите использовать только те свойства, которые имеют сеттеры, вы должны удалить флаг BindingFlags.GetProperty. Но я не проверял это, поэтому я могу ошибаться.

Мой ответ получил -1. Так что, похоже, мой ответ неверный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...