Indirection sur les membres d'une classe en vb.net ou c#, indirection on class members in vb.net or c#

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 564 fois - Téléchargée 19 fois

Contenu du snippet

Bonjour,

Ayant fait un peu de Windev, la fonction la plus pratique de ce langage est que l'on peut faire de l'indirection sur n'importe quelle variable, c'est à dire y accéder en lecture et en écriture en construisant son nom dans une chaîne de caractère. C'est quelque chose qui n'est pas proposé en standard dans le FrameWork .NET et nombreux sont ceux qui se sont arrachés les cheveux en essayant de faire de l'indirection en .NET, car il faut avouer que c'est bien pratique lorsqu'on en a besoin. Le Framework .NET propose bien quelque chose pour les System.Windows.Forms, la propriété Controls. Mais c'est limité aux Form et ça ne permet surtout pas d'accéder aux membres ajoutés dans notre classe héritée de Form. "Me.Controls" n'est pas assez, il faudrait un "Me.Members".

Ma source propose donc une alternative qui fonctionne pour les membres de toutes les classes.

Qu'est ce que l'indirection, concrètement ?

C'est très simple :

Imaginez que vous avez 150 membres dans votre classe, nommés Membre1, Membre2, Membre3, ..., Membre150. Bon bien entendu une telle classe souffrirait d'un sérieux problème de conception, mais c'est juste pour l'exemple.
Imaginez ensuite que vous désiriez assigner une valeur à ces 150 membres. C'est fastidieux de le faire à la main...

On écrira donc :

Membre1 = 10
Membre2 = 10
Membre3 = 10
...
Membre150 = 10

Vous pouvez imaginer que c'est très long et très ennuyeux.
Que diriez vous de faire à la place :

Dim i as Integer
For i = 1 To 150
IndirectionSet(Me, Me.GetType(), "Membre" & i, 10)
Next

Et voilà, plus que 4 lignes de code !
La même chose pour l'accès en lecture :

Dim i as Integer
For i = 1 To 150
MsgBox( Indirection(Me, Me.GetType(), "Membre" & i) )
Next

Je pense que vous commencez à comprendre l'intérêt de la courte source que je vais vous proposer. Voyez plutôt le code. J'ai utilisé l'espace de nom System.Reflection pour arriver à mes fins. Il suffit donc d'importer System.Reflection puis de copier et coller ces deux procédures dans votre classe.

Source / Exemple :


' Au début de votre classe, n'oubliez pas d'importer cet espace de nom
Imports System.Reflection

Public Class MaClasse

    Public Membre1 As Integer
    Public Membre2 As Integer
    Public Membre3 As Integer
    ' et on ajoute jusqu'à 150...
    Public Membre150 As Integer

    Public Sub New()

        Dim i As Integer
        For i = 1 To 150
            'On assigne la valeur de chaque membre à la valeur 10
            IndirectionSet(Me, Me.GetType(), "Membre" & i, 10)

            'On affiche la valeur de chaque membre
            MsgBox( DirectCast(Indirection(Me, Me.GetType(), "Membre" & i), Integer) )
        Next

    End Sub

    ''' <summary>
    ''' Permet de récupérer la valeur du membre "membername" de l'objet "obj" de type "objtype"
    ''' </summary>
    ''' <param name="obj">Objet parent du membre dont on souhaite récupérer la valeur</param>
    ''' <param name="objtype">Type de l'objet parent</param>
    ''' <param name="membername">Nom du membre</param>
    ''' <returns>La valeur du membre spécifié. Si le membre n'est pas trouvé, une exception est levée.</returns>
    ''' <remarks></remarks>
    Private Function Indirection(ByRef obj As Object, ByVal objtype As Type, ByVal membername As String) As Object

        Dim fi As FieldInfo
        fi = objtype.GetField(membername)
        Return fi.GetValue(obj)

    End Function

    ''' <summary>
    ''' Permet d'assigner une valeur "value" au membre "membername" de l'objet "obj" de type "objtype"
    ''' </summary>
    ''' <param name="obj">Objet parent du membre à assigner</param>
    ''' <param name="objtype">Type de l'objet parent</param>
    ''' <param name="membername">Nom du membre</param>
    ''' <param name="value">Valeur du membre</param>
    ''' <remarks></remarks>
    Private Sub IndirectionSet(ByRef obj As Object, ByVal objtype As Type, ByVal membername As String, ByRef value As Object)

        Dim fi As FieldInfo
        fi = objtype.GetField(membername)
        fi.SetValue(obj, value)

    End Sub

End Class

Conclusion :


Ma petite source permettra à ceux qui désirent accéder aux membres d'un objet par leur nom et permet non seulement un gain de temps mais aussi un gain en visibilité. Le code est beaucoup plus court !

A voir également

Ajouter un commentaire

Commentaires

Bon Gabsoftware,

Tout d'abord merci pour tes explications cela va m'être fort utile.
Existe t'il par hasard le principe d'indirection concernant les membres d'une structure.

J'ai essayé de transposé ton code, mais les membres de ma structure ne sont pas affectés.
Messages postés
14476
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
11 juillet 2020
420 > SIVSAW
Bonjour comme l’a fait remarquer Charles Récaud, en .Net on parle de Réflection et pas d’indirection. Je ne me suis jamais posé la question si la reflection marche avec une structure, mais en cherchant vite fait, j’ai vu des sujets résolus sur le net. Donc ça devrait.
Cependant l’usage des structures est déconseillé. La principale raison d'être est la compatibilité avec des dll codés dans un langage plus anciens.
Côté inconvénients
-C’est un type valeur, donc ça consomme de la mémoire inutilement à chaque passage en paramètres.
-Ça n’encapsule pas les variables.
-Y’a pas d’héritage.
-On ne peut pas faire de binding.
-Evidement, pas de méthode ni événement.

Bref c’est pas un objet, .Net est un langage objet. Utiliser une structure c’est aller à l’encotre du principe du lanage et du coup passer à côté de tous les points forts.
Messages postés
127
Date d'inscription
lundi 11 octobre 2004
Statut
Membre
Dernière intervention
18 mai 2016

Oui Bouv, et j'ai beau relire, je ne trouve pas la réponse à ma question (la dernière, pas la première)... Peut-être parce que je ne maîtrise pas du tout ce sujet.

Par contre, le dernier commentaire de hier soir de Charles Racaud, là, je comprends l'avantage maintenant, quand on a des membres non ordonnées. Il y en a peut-être d'autres...
Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
Il est vrai que si c'est pour faire des membres indexés de 0 à n (ou tous les membres sont utilisées), il vaut mieux un tableau d'object. Un object est la base de tout type, donc il n'y a pas d'inconvénient ni de perte de mémoire.
Je vois plutôt l'utilité ici pour récupéré des index non ordonnées. Juste des membre dont les index ne sont pas ordonnées (4, 6, 897, 7, 9876...) ou encore mettre un Id à la place d'un index. Mais la aussi, on peut remplacer par un Dictionary.
Il est vrai que utiliser la Reflection n'est pas trop conseiller ici si c'est pour utiliser dans un même projet. Mieux vaut utiliser les différents outils du framework, list, dictionary, ...
Source à utiliser pour de bonnes raisons.
__
Kenji
Messages postés
1411
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
3 mars 2019
1
PWM>>As-tu lu mon commentaire et celui de Charles Racaud ?
Afficher les 15 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.