简体   繁体   中英

Is there a C# equivalent of typeof for properties/methods/members?

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)

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.

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

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.

Now in c#, we have nameof() .

Ref link

不,c# 中没有这样的语法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM