Есть ли в C # эквивалент typeof для свойств / методов / членов? - PullRequest
18 голосов
/ 19 марта 2010

Метаданные Type классов могут быть получены несколькими способами. Два из них:

var typeInfo = Type.GetType("MyClass")

и

var typeInfo = typeof(MyClass)

Преимущество второго способа заключается в том, что опечатки будут перехвачены компилятором, и среда IDE сможет понять, о чем я говорю (что позволяет таким функциям, как рефакторинг, работать без нарушения кода)

Существует ли эквивалентный способ строгой ссылки на элементы / свойства / методы для метаданных и отражения? Могу ли я заменить:

var propertyInfo = typeof(MyClass).GetProperty("MyProperty")

с чем-то вроде:

var propertyInfo = property(MyClass.MyProperty)

Ответы [ 4 ]

17 голосов
/ 19 марта 2010

Нет, к сожалению, нет. Это обсуждалось и даже называлось: infoof (произносится как «in-foof» для комедийного значения), но не было реализовано ... пока. У Эрика Липперта есть сообщение в блоге об этом .

Самое близкое, что вы можете сделать в C # 3, - это заставить компилятор сгенерировать дерево выражений, а затем извлечь его из этого - но это вряд ли приятно.

10 голосов
/ 11 ноября 2011

Я только что реализовал эквивалент конструкций 'property of' 'methodof' 'fieldof' с использованием Syste.Linq.Expressions

поэтому вместо написания

var mi = typeof (string).GetMethod("Concat", new[] {typeof (object), typeof (object)});

Вы можете использовать:

var mi = ReflectionHelper.MethodOf(() => string.Concat(new object(), new object()));

Зачем нам это нужно? потому что теперь мы безопасны для метода рефакторинга, мы используем через отражение

список вспомогательного класса (вам может понадобиться добавить некоторые информативные исключения в методы):

/// <summary>
/// Represents a set of helpers for .net reflection
///  </summary>
public static class ReflectionHelper
{
    #region Public methods

    /// <summary>
    /// Gets a MethodInfo object from specified expression
    ///  </summary>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="methodExpression"></param>
    /// <returns></returns>
    public static MethodInfo MethodOf<TResult>(Expression<Func<TResult>> methodExpression)
    {
        return ((MethodCallExpression)methodExpression.Body).Method;
    }

    /// <summary>
    /// Gets a MethodInfo object from specified expression
    ///  </summary>
    /// <param name="methodExpression"></param>
    /// <returns></returns>
    public static MethodInfo MethodOf(Expression<Action> methodExpression)
    {
        return ((MethodCallExpression)methodExpression.Body).Method;
    }

    /// <summary>
    /// Gets a MethodInfo object from specified expression
    ///  </summary>
    /// <param name="methodExpression"></param>
    /// <returns></returns>
    public static MethodInfo MethodOf<TInstance, TResult>(Expression<Func<TInstance, TResult>> methodExpression)
    {
        return ((MethodCallExpression)methodExpression.Body).Method;
    }

    /// <summary>
    /// Gets a MethodInfo object from specified expression
    ///  </summary>
    /// <param name="methodExpression"></param>
    /// <returns></returns>
    public static MethodInfo MethodOf<TInstance>(Expression<Action<TInstance>> methodExpression)
    {
        return ((MethodCallExpression)methodExpression.Body).Method;
    }

    /// <summary>
    /// Gets a PropertyInfo object from specified expression
    ///  </summary>
    /// <param name="propertyGetExpression"></param>
    /// <returns></returns>
    public static PropertyInfo PropertyOf<TProperty>(Expression<Func<TProperty>> propertyGetExpression)
    {
        return ((MemberExpression)propertyGetExpression.Body).Member as PropertyInfo;
    }

    /// <summary>
    /// Gets a PropertyInfo object from specified expression
    ///  </summary>
    /// <param name="propertyGetExpression"></param>
    /// <returns></returns>
    public static PropertyInfo PropertyOf<TInstance, TProperty>(Expression<Func<TInstance, TProperty>> propertyGetExpression)
    {
        return ((MemberExpression)propertyGetExpression.Body).Member as PropertyInfo;
    }

    /// <summary>
    /// Gets a FieldInfo object from specified expression
    ///  </summary>
    /// <param name="fieldAccessExpression"></param>
    /// <returns></returns>
    public static FieldInfo FieldsOf<TProperty>(Expression<Func<TProperty>> fieldAccessExpression)
    {
        return ((MemberExpression)fieldAccessExpression.Body).Member as FieldInfo;
    }

    //TODO: ConstructorOf(...)

    #endregion //Public methods
}

как я понимаю, мы не можем использовать один и тот же подход для getParameterInfo или EventInfo

Другой подход к этому, описанный Jb Evain, см .: http://evain.net/blog/articles/2010/05/05/parameterof-propertyof-methodof?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+jbevain+%28Jb+in+a+nutshell%29

4 голосов
/ 17 июля 2016

В c # 6 все еще нет infoof, но есть nameof:

var propertyInfo = typeof(MyClass).GetProperty(nameof(MyClass.MyProperty))

Это, конечно, не более кратко, но, по крайней мере, это дружественный рефакторинг.

0 голосов
/ 19 марта 2010

Нет, в c # такого синтаксиса нет.

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