C# Reflection - Get PropertyInfo without a string

2019-04-13 16:58发布

问题:

This question already has an answer here:

  • How to get the PropertyInfo of a specific property? 4 answers

I have a property in Myclass:

public class MyClass{    
    public string FirstName {get;set;}
}

How can I get the PropertyInfo (using GetProperty("FirstName")) without a string?

Today I use this:

PropertyInfo propertyTitleNews = typeof(MyClass).GetProperty("FirstName");

Is there a way for use like this:

PropertyInfo propertyTitleNews = typeof(MyClass).GetProperty(MyClass.FirstName);

?

回答1:

See here. The idea is to use Expression Trees.

public static string GetPropertyName<T, TReturn>(Expression<Func<T, TReturn>> expression)
{
    MemberExpression body = (MemberExpression)expression.Body;
    return body.Member.Name;
}

And then use it like:

var name = GetPropertyName<MyClass, string>(c => c.FirstName);

A bit cleaner solution would be if one would not required to specify so much generic parameters. And it is possible via moving MyClass generic param to util class:

public static class TypeMember<T>
{
    public static string GetPropertyName<TReturn>(Expression<Func<T, TReturn>> expression)
    {
        MemberExpression body = (MemberExpression)expression.Body;
        return body.Member.Name;
    }
}

Then usage will be cleaner:

var name = TypeMember<MyClass>.GetPropertyName(c => c.FirstName);


回答2:

Another possibility, beside Ivan Danilov's answer, is to provide an extension method:

public static class PropertyInfoExtensions
{
    public static string GetPropertyName<TType, TReturnType>(
        this TType @this,
        Expression<Func<TType, TReturnType>> propertyId)
    {
        return ((MemberExpression)propertyId.Body).Member.Name;
    }
}

And then use it like this:

MyClass c;
PropertyInfo propertyTitleNews = c.GetPropertyName(x => x.FirstName);

The drawback is that you need an instance, but an advantage is that you don't need to supply generic arguments.



回答3:

You could do that

var property = ExpressionExtensions.GetProperty<MyClass>(o => o.FirstName);

With this helper :

public static PropertyInfo GetProperty<T>(Expression<Func<T, Object>> expression)
{
     MemberExpression body = (MemberExpression)expression.Body;
     return typeof(T).GetProperty(body.Member.Name);
}


标签: c# reflection