2008-10-27 19 views
25

Je travaille actuellement sur un projet où une section du code ressemble à ceci:invoquez propriétés par nom Dynamiquement de chaîne en utilisant VB.NET

Select Case oReader.Name 
    Case "NameExample1" 
     Me.Elements.NameExample1.Value = oReader.ReadString 
    .... 
    Case "NameExampleN" 
     Me.Elements.NameExampleN.Value = oReader.ReadString 
    .... 
End Select 

Il continue pendant un certain temps. Le code est évidemment verbeux et il sent comme il pourrait être amélioré. Est-il possible d'invoquer dynamiquement une propriété VB.NET telle que quelque chose comme cela peut être fait:

Dim sReadString As String = oReader.ReadString 
Me.Elements.InvokeProperty(sReadString).Value = sReadString 

Répondre

15

D'autres ont répondu parfaitement raisonnable, mais Juste au cas où il s'agit d'un morceau de code sensible à la performance, vous pourriez vouloir compiler les appels réflexifs dans les délégués.

J'ai un blog entry pour transformer MethodBase.Invoke en délégués. Le code est en C#, mais la même technique peut également être appliquée à VB.NET. Pour l'utiliser avec les propriétés, obtenez la méthode "setter" appropriée avec PropertyInfo.GetSetMethod, puis créez un délégué qui l'appelle. Vous pouvez avoir une carte du nom du champ à "déléguer à appeler pour définir le champ".

Juste pour réitérer, c'est seulement vraiment nécessaire si c'est dans un bout de code critique de performance. Sinon, vous pouvez toujours créer un Dictionary<string, PropertyInfo> pour éviter d'appeler GetProperty plusieurs fois, mais l'étape pour le convertir en délégué ne vaut probablement pas la peine d'être inquiétée.

+3

CallByName semble plus simple. En quoi cela diffère-t-il de la réflexion en termes de performance? – EndangeredMassa

+0

Je crois que CallByName utilise la réflexion en interne, et je suspecte appliquer diverses manigances VB-spécifiques pour la compatibilité descendante. Testez-le, mais je doute fort que vous le verrez aussi rapide qu'un délégué. Oui, utiliser MakeDelegate est plus compliqué, mais beaucoup plus performant que la réflexion. –

+0

votre lien d'entrée de blog est cassé – Fredou

30

Je ne peux pas croire que les autres affiches vous ont dit d'utiliser la réflexion. VB comme une fonction CallByName qui fait exactement ce que vous voulez.

+7

Merde, je voudrais savoir à propos de cela il y a des années. –

6

Ouais ... CallByName

10

Oui, CallByName est la meilleure solution pour vous. Voici l'instruction de le faire:

CallByName(yourClassOrObjectName,"NameExample1",CallType.Set,oReader.ReadString) 

Vous pouvez écrire "NameExample" à la place de "NameExample1". Mentionnez que ce troisième paramètre vous permet de 'Get', 'Let' de ce paramètre (et même d'invoquer n'importe quelle méthode).
Vous pouvez donc obtenir la valeur de votre paramètre en utilisant CallType.Get.