Comment obtenir un nom de propriété d'un type donné fortement typé?

.net c# expression-trees reflection

Question

Je voudrais pouvoir récupérer le nom d'une propriété d'un type en utilisant une syntaxe fortement typée. J'ai déjà une fonction pour obtenir le nom de propriété d'une instance:

public static string PropertyName<T, TReturn>(this T obj, Expression<Func<T, TReturn>> property) where T : class 
{
    MemberExpression body = (MemberExpression) property.Body;
    if (body == null) throw new ArgumentException("The provided expression did not point to a property.");       
    return body.Member.Name;
}

Ce qui peut s'appeler comme ça:

Car car = new Car();
car.PropertyName(x => x.Wheels) //returns "Wheels"

J'essaie de créer une autre fonction qui pourrait prendre en charge les éléments suivants:

Type t = Typeof(Car);
t.PropertyName(x => x.Wheels) //should return "Wheels"

Ou tout simplement (encore mieux!):

Car.PropertyName(x => x.Wheels)

Comment pourrais-je m'y prendre?

Réponse acceptée

Vous pouvez réécrire votre méthode pour l'utiliser sans créer d'instance:

var prop = ReflectionHelper.PropertyName<Car>(x => x.Wheels);

parce que tu n'utilises pas obj inside parce que tu n'en as pas besoin:

public static class ReflectionHelper
{
    public static string PropertyName<T>(Expression<Func<T, object>> property) where T : class 
    {
        MemberExpression body = (MemberExpression)property.Body;
        return body.Member.Name;
    }
}

Notez que le type de retour n'a pas besoin d'être fortement typé, il peut simplement s'agir d'un object .


Réponse populaire

L'exemple @abatishchev ne fonctionne que si Wheels est un type de référence.

Si vous avez ce qui suit

public class Car
{
   public int ID;
}

Et vous essayez d'appeler ça

var prop = ReflectionHelper.PropertyName<Car>(x => x.ID);

Vous obtiendrez l'exception suivante

InvalidCastException: impossible de convertir l'objet de type 'System.Linq.Expressions.UnaryExpression' en type 'System.Linq.Expressions.MemberExpression'.

Je pense que cela a à voir avec le fait que vous passez un type de valeur à l'expression, il doit donc être mis en boîte dans un objet. Si vous passez un type de référence, il n’est pas nécessaire de le mettre en boîte pour l’objet.

Voici ce que vous pouvez faire à la place:

var prop = ReflectionHelper.PropertyName((Car x) => x.Wheels);

public static class ReflectionHelper
{
    public static string PropertyName<T, P>(Expression<Func<T, P>> property) 
        where T : class 
    {
        MemberExpression body = (MemberExpression)property.Body;
        return body.Member.Name;
    }
}



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi