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 !
Modifié le 23 avril 2018 à 16:57
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.
23 avril 2018 à 15:50
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.
27 oct. 2009 à 09:51
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...
26 oct. 2009 à 20:29
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
26 oct. 2009 à 17:46
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.