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.
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.
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...
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
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 ?
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
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)
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.
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.
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.
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 ?)
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
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.
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.
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...
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