2008-11-13 8 views
4

L'utilisateur de StackOverflow jolson avait un très bon morceau de code qui illustre comment on peut enregistrer des menthods sans utiliser de chaînes, mais des arbres d'expressions here.Récupère le nom d'une propriété en la passant à une méthode

Est-il possible d'avoir quelque chose de similaire pour les propriétés au lieu des méthodes? Passer une propriété (pas le nom de la propriété) et à l'intérieur de la méthode pour obtenir le nom de la propriété?

Quelque chose comme ceci:


    RegisterMethod(p => p.Name) 

    void RegisterMethod(Expression??? propertyExpression) where T : Property ??? 
    { 
     string propName = propertyExpression.Name; 
    } 

Merci.

Répondre

6

Vous pouvez écrire quelque chose le long de cette:

static void RegisterMethod<TSelf, TProp> (Expression<Func<TSelf, TProp>> expression) 
{ 
    var member_expression = expression.Body as MemberExpression; 
    if (member_expression == null) 
     return; 

    var member = member_expression.Member; 
    if (member.MemberType != MemberTypes.Property) 
     return; 

    var property = member as PropertyInfo; 
    var name = property.Name; 

    // ... 
} 
+0

Pourquoi le TProp est-il nécessaire? J'ai testé et ça marche, mais je réalise que j'ai besoin d'apprendre des arbres d'expression. –

+0

@Vasi - le type de lambda doit être explicite. Vous ne pouvez pas, par exemple, simplement utiliser 'Expression'. Le TProp se réfère ici à l'int qui décrit la propriété. Vous pouvez laisser le compilateur le comprendre, cependant. –

+0

TProp exprime le type de retour de la propriété, et est nécessaire pour décrire une méthode qui prend quelque chose, et renvoie quelque chose d'autre, à savoir: le Func . Ensuite, l'arborescence d'expression est construite sur ce type de délégué. –

7

J'ai posté un exemple complet de ce here (voir aussi le poste de « this » dessous)

note qu'il traite de la LambdaExpression etc. En tant que mise à jour du code tel que publié, vous pouvez en ajouter un peu plus pour faciliter son utilisation dans certains scénarios:

static class MemberUtil<TType> 
{ 
    public static string MemberName<TResult>(Expression<Func<TType, TResult>> member) 
    { 
     return MemberUtil.MemberName<TType, TResult>(member); 
    } 
} 

n vous pouvez utiliser l'inférence de type générique pour la valeur de retour:

string test1 = MemberUtil<Foo>.MemberName(x => x.Bar); 
string test2 = MemberUtil<Foo>.MemberName(x => x.Bloop()); 
+0

Bonjour Marc, Merci beaucoup, c'était exactement ce que je cherchais, pour ignorer en quelque sorte le type de la propriété. –

+0

@Vasi - génériques sont "tout ou rien" quand il s'agit de l'inférence de type (peut-être nous aurons "mumble" taper à un moment donné). L'astuce ci-dessus permet au compilateur d'inférer le type de propriété sans avoir à le spécifier nous-mêmes ;-p –

Questions connexes