Нахождение хостинга PropertyInfo из MethodInfo метода получения / установки - PullRequest
23 голосов
/ 06 февраля 2009

Я делаю анализ типов во время выполнения, используя Reflection. Если у меня есть экземпляр MethodInfo, Как я могу выяснить, является ли это «реальным» методом или методом получения / установки свойства? И если это свойство, как я могу найти его хостинг PropertyInfo назад?

Ответы [ 5 ]

17 голосов
/ 06 февраля 2009

Что ж, метод, стоящий за геттером и сеттером , это"настоящие" методы.

Повторное отслеживание обратно к свойству - шаблон (возврат против принятия 1 аргумента) поможет сузить его - но вам придется вызывать GetGetMethod / GetSetMethod для каждого, чтобы найти свойство.

Вы могли бы вероятно попробовать Name (меньше get __ / set__) - но это кажется хрупким. Вот более длинная версия (без использования Name):

static PropertyInfo GetProperty(MethodInfo method)
{
    bool takesArg = method.GetParameters().Length == 1;
    bool hasReturn = method.ReturnType != typeof(void);
    if (takesArg == hasReturn) return null;
    if (takesArg)
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
    }
    else
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetGetMethod() == method).FirstOrDefault();
    }
}
7 голосов
/ 06 февраля 2009

Ecma 335 указывает (но не требует), чтобы компиляторы использовали префиксы get_ / set_ (глава 22.28). Я не знаю ни одного языка, который нарушает эту рекомендацию. Сделать это просто:

public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) {
  if (!method.IsSpecialName) return null;
  return t.GetProperty(method.Name.Substring(4), 
    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
}
5 голосов
/ 29 декабря 2012

Мне бы очень хотелось оставить это как комментарий, но я не могу, так как мой представитель недостаточно высок: (

В коде Марка Гравелла есть ошибка: если это индексатор, он вернет ноль, даже если родительское свойство существует. Приятно иметь такой быстрый сбой, но я думаю, что мы можем сделать это только тогда, когда у него нет ни возвращаемого значения, ни параметра:

    [Pure]
    public static PropertyInfo GetParentProperty(this MethodInfo method)
    {
        if (method == null) throw new ArgumentNullException("method");
        var takesArg = method.GetParameters().Length == 1;
        var hasReturn = method.ReturnType != typeof(void);
        if (!(takesArg || hasReturn)) return null;

        if (takesArg && !hasReturn)
        {
            return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method);
        }
        else
        {
            return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method);
        }
    }
5 голосов
/ 06 февраля 2009

Посмотрите на MethodBase.IsSpecialName. Методы, которые не должны быть четко видны, такие как методы доступа к свойствам, методы подписки на события и перегрузки операторов, используют этот флаг.

Насколько мне известно, нет способа найти PropertyInfo без итерации по свойствам и сравнения методов.

0 голосов
/ 22 сентября 2015

Трюк для игры: BindingFlags.DeclaredOnly и IsSpecialName

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