Is there a C# equivalent of typeof for properties/

2019-04-18 18:51发布

A classes Type metadata can be obtained in several ways. Two of them are:

var typeInfo = Type.GetType("MyClass")

and

var typeInfo = typeof(MyClass)

The advantage of the second way is that typos will be caught by the compiler, and the IDE can understand what I'm talking about (allowing features like refactoring to work without silently breaking the code)

Does there exist an equivalent way of strongly referencing members/properties/methods for metadata and reflection? Can I replace:

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

with something like:

var propertyInfo = property(MyClass.MyProperty)

4条回答
劫难
2楼-- · 2019-04-18 18:53

No, there is no such syntax in c#.

查看更多
仙女界的扛把子
3楼-- · 2019-04-18 19:04

In c# 6 there's still no infoof but there is nameof:

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

It's certainly not more terse, but at least it's refactoring friendly.

查看更多
混吃等死
4楼-- · 2019-04-18 19:07

No, unfortunately not. It's been discussed and even named: infoof (pronounced "in-foof" for comedy value) but it's not been implemented... yet. Eric Lippert has a blog post about it.

The closest you can come in C# 3 is to make the compiler generate an expression tree, and then pull it out of that - but that's hardly pleasant.

查看更多
甜甜的少女心
5楼-- · 2019-04-18 19:16

I've just implemented an equivalent of constructions 'propertyof' 'methodof' 'fieldof' using Syste.Linq.Expressions

so instead of writing

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

you can use:

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

Why do we need this? because now we safe to refactor method, we use via reflection

listing of helper class (you may need to add some informative exceptions in methods):

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

as I understand we could not use same aproach to getParameterInfo or EventInfo

Another approach to do that, described by Jb Evain, see: 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

查看更多
登录 后发表回答