2017-07-29 2 views
1

Je souhaite transmettre une propriété à une fonction de telle sorte que la fonction connaisse à la fois la valeur de la propriété et le nom de la propriété. C'est ainsi que je peux retourner les erreurs qui correspondent aux noms de propriétés.C# Passer/récupérer un nom de propriété à partir d'un paramètre sans réflexion

J'ai actuellement le code comme ceci:

var userNameField = personField.GetChildField(f => f.UserName, nameof(personField.Value.UserName)); 

plusieurs fois répétées, de sorte que le 2ème paramètre est le nom de la propriété à l'intérieur du lambda du 1er paramètre.

Est-il possible d'automatiser ce paramètre si:

  1. Le code en double est allé
  2. Le nom de la chaîne de la propriété est calculée à la compilation, pas d'exécution pour chaque appel

Idéalement je voudrais mon code pour simplement ressembler à:

var userNameField = personField.GetChildField(f => f.UserName); 

Je Cela a fonctionné en utilisant la réflexion en utilisant Expression<Func..., c'est-à-dire ((MemberExpression) getPropertyFunc.Body).Member.Name; mais ceci est trop lent, en particulier en compilant l'expression dans une fonction que je peux utiliser pour récupérer la valeur de la propriété.

De même, j'ai lu à travers les idées ici: Get name of property as a string

Est-il possible de peupler le nom de la propriété de la fonction GetChildField au moment de la compilation? Ou l'encoder dans le modèle en quelque sorte?

+0

Si la compilation de l'expression est trop lent, avez-vous essayé la mise en cache le résultat de cette compilation? Le premier appel ne serait pas plus rapide, mais les appels ultérieurs pourraient en bénéficier. De plus, puisque vous semblez n'accepter que les expressions de la forme 'x => x.Property', avez-vous essayé d'obtenir la propriété par réflexion au lieu de compiler l'expression? –

+0

Est-il possible de mettre en cache le résultat de la compilation? J'appelle la méthode qui compile l'expression avec de nombreuses expressions différentes dans la base de code, de sorte qu'elle doit être mise en cache par appel. Votre deuxième point est correct cependant. J'ai réussi à améliorer la performance en supprimant la compilation et en obtenant la propriété par réflexion, mais ce n'est toujours pas idéal car le nom de la propriété est toujours calculé au moment de l'exécution (je crois ... à moins que le compilateur ne fasse quelque chose de funky). –

Répondre

-1

Selon la documentation Roslyn trouvé here l'opérateur nameof est évalué à la compilation par la première ligne sous la section « Sémantique » qui lit

L'expression NomDe est une constante. Dans tous les cas, nameof (...) est évalué à la compilation pour produire une chaîne. Son argument n'est pas évalué à l'exécution et est considéré comme un code inaccessible (cependant, il n'émet pas d'avertissement de "code inaccessible").

0

Il est possible en suivant:

Item model=new Item();  
var propertyInfo = model.GetType();  
var value=propertyInfo.GetProperty("IrrA").GetValue(model, null).ToString(); 
+0

Le PO n'a-t-il pas demandé de solution de réflexion? – kuskmen

+0

@kuskmen En fait non, OP n'a pas demandé de solution de réflexion. OP a seulement déclaré que compiler une expression était trop lent. Cela pourrait être plus rapide que de compiler l'expression (ou non - je n'ai pas testé). –

+0

J'ai demandé une solution qui a calculé le nom de la propriété au moment de la compilation, pas l'exécution. Cependant, cette solution est plus rapide que la compilation de l'expression. –