INDIRECTION SUR LES MEMBRES D'UNE CLASSE EN VB.NET OU C#, INDIRECTION ON CLASS M

oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010 - 19 oct. 2009 à 16:58
Whismeril Messages postés 19093 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 16 juillet 2024 - 23 avril 2018 à 16:55
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/50710-indirection-sur-les-membres-d-une-classe-en-vb-net-ou-c-indirection-on-class-members-in-vb-net-or-c

Whismeril Messages postés 19093 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 16 juillet 2024 658
Modifié le 23 avril 2018 à 16:57
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.
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.
PWM63 Messages postés 127 Date d'inscription lundi 11 octobre 2004 Statut Membre Dernière intervention 18 mai 2016
27 oct. 2009 à 09:51
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...
Utilisateur anonyme
26 oct. 2009 à 20:29
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
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
26 oct. 2009 à 17:46
PWM>>As-tu lu mon commentaire et celui de Charles Racaud ?
PWM63 Messages postés 127 Date d'inscription lundi 11 octobre 2004 Statut Membre Dernière intervention 18 mai 2016
26 oct. 2009 à 17:38
oulaaa... ca a bien l'air compliqué... ca existe pas les tableaux sous windev ?
si je dois gérer des membres, si j'en ai 2, j'utiliserai membre1 et membre2, mais si j'en ai 150, je fais 1 tableau membres(150) as cequejeveux... d'ailleurs, j'ai toujours fait comme ca... depuis le gfa...
bref, je me pose 1 question tout simple : est-ce qu'il y a 1 avantage avec ta méthode par rapport à 1 simple tableau ?
Utilisateur anonyme
26 oct. 2009 à 11:56
J'y ajouterai ces deux méthodes pour une assignation et une récupération sécurisé si les membres sont de différents types.

Public Function GetMembre(Of T)(ByVal Index As Integer) As T
Dim oType As Type = MyClass.GetType
Dim FI As FieldInfo = oType.GetField("Membre" & Index.ToString)
If Type.Equals(FI.FieldType, GetType(T)) Then
Return CType(FI.GetValue(Me), T)
Else
Throw New InvalidCastException(String.Format("Unable to cast object of type '{0}' to type '{1}'", FI.FieldType, GetType(T)))
End If
End Function

Public Sub SetMembre(Of T)(ByVal Index As Integer, ByVal Value As T)
Dim oType As Type = Me.GetType
Dim FI As FieldInfo = oType.GetField("Membre" & Index.ToString)
If Type.Equals(FI.FieldType, GetType(T)) Then
FI.SetValue(Me, Value)
Else
Throw New InvalidCastException(String.Format("Unable to cast object of type '{0}' to type '{1}'", GetType(T), FI.FieldType))
End If
End Sub
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
21 oct. 2009 à 11:27
Tout à fait d'accord.. il s'agit simplement d'un arbitrage
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
21 oct. 2009 à 09:13
Oui après il faut voir d'un point de vue pratique : on peut renoncer au modèle normalisé des BDD (pas de champ en double) pour des raisons de performance ou de simplicité, il faut peser le pour et le contre. C'est bien expliqué ici (voir les exemples) :
Forme normale (bases de données relationnelles)
http://fr.wikipedia.org/wiki/Forme_normale_(bases_de_donn%C3%A9es_relationnelles)
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
21 oct. 2009 à 08:49
Tout à fait d'accord sur le principe, il existe plusieurs manières d'arriver au même résultat en programmation. Et l'indirection peut être contournée dans la majorité des cas.

Mais en dehors de toutes contraintes de performance mon seul soucis est d'avoir le code le plus simple et lisible possible. Ce genre de code me va donc très bien.

PS : Level1 à Level5, il s'agit d'un logiciel de GED et chaque table gère un niveau. En factorisant certains champs, je créé de nouvelles tables? Or, toujours dans un soucis de praticité je code une classe de pilotage par table dans ma BDD. Donc plus de tables => plus de classes.
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
21 oct. 2009 à 08:37
Hum : LEVEL1 à LEVEL5 : là aussi d'autres personnes auraient peut être résolut le problème de manière différente : en factorisant une table commune, puis en créant des liens pour les tables contenant d'autres champs, avec au final pas de champ en commun, donc pas besoin d'indirection (mais une BDD plus complexe quand même). Je sais qu'il doit exister des cas où l'indirection peut servir, mais à mon avis, ce n'est pas fréquent, et c'est plus une question d'habitude de programmation à mon avis.
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
20 oct. 2009 à 17:50
Patrice99>>Effectivement l'exemple présenté peux être remplacé par un tableau puisque toutes les valeurs renvoyées sont du même type. Mais on pourrait très bien renvoyer des données ou objets de type différent.
Exemple, je suis en train de developper un logiciel de BDD avec les tables suivantes LEVEL1, LEVEL2... LEVEL5. Les tables possèdent des champs identiques et des champs différents. J'ai donc codé une classe pour chacune d'elle (cLevel1... cLevel5). Pas de tableau possible car les objets sont de type différent. Pour savoir à quelle classe accéder, je dois à chaque dois utiliser un Select Case 'Integer'. Ce genre de code me permettrait de m'en passer.
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
20 oct. 2009 à 16:19
L'exemple que tu as donné peut être remplacé par un tableau. Peut-tu donner un autre exemple ? (peut être pour faire du scripting, mais dans ce cas, il vaudrait mieux un moteur de script ? franchement je ne voie pas l'intérêt de la chose, et je me demande si ce n'est pas simplement une mauvaise habitude importée de Windev ?)
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
20 oct. 2009 à 11:03
Bon exemple, mais un peu plus simple d'appel en utilisant une propriété :

Public Property Membre(ByVal Index As Integer) As Integer
Get
Dim oType As Type = Me.GetType
Dim FI As FieldInfo = oType.GetField("Membre" & Index.ToString)
Return FI.GetValue(Me)
End Get
Set(ByVal value As Integer)
Dim oType As Type = Me.GetType
Dim FI As FieldInfo = oType.GetField("Membre" & Index.ToString)
FI.SetValue(Me, value)
End Set
End Property

On utilise ensuite :

Membre(i) = 10
MsgBox Membre(i)
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
19 oct. 2009 à 16:58
C'est simple et efficace. mais surtout tu m'apprends un truc, et comment l'exploiter.
Rejoignez-nous