Affecter valeur à tableau défini dans une structure (VB.NET)
Résolu
danyvio
Messages postés
4
Statut
Membre
-
danyvio Messages postés 4 Statut Membre -
danyvio Messages postés 4 Statut Membre -
Bonjour ! J'essaie de m'initier pour mon plaisie à VB.net et je me bats pour résoudre un cas apparemment banal :
Tout d'abord j'ai une expérience de 45 ans de programmation de langages divers et variés, et j'ai essayé pas mal de choses avant de poser ce qui suit (j'ai purgé ce qui ne servait pas à la compréhension du problème)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::
Le programme connaît bien l'affectation Jeu_initial.Niv_appel = 6
Par contre, à l'exécution j'ai l'erreur sur la première ligne d'affectation : Jeu_initial.Plq(1).Valeur = 0
erreur : L'exception NullReferenceException n'a pas été gérée, La référence d'objet n'est pas définie à une instance d'un objet.
J'ai l'expérience du C où une structure contenant elle-même des structures en cascade ne pose pas de problème.
Toute aide sera bienvenue, sans m'orienter SVP vers la POO ou autre. Par conviction je veux comprendre ce problème précis. Merci d'avance !!
Tout d'abord j'ai une expérience de 45 ans de programmation de langages divers et variés, et j'ai essayé pas mal de choses avant de poser ce qui suit (j'ai purgé ce qui ne servait pas à la compréhension du problème)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Module Module1
Public Structure Plaque
Public Valeur As UInteger
End Structure
Public Structure Jeu
Public Plq() As Plaque
Public Niv_appel As Integer
Public Sub Initialize()
ReDim Plq(6)
End Sub
End Structure
Public Jeu_initial As Jeu
Public Sub Main()
Jeu_initial.Niv_appel = 6
Jeu_initial.Plq(1).Valeur = 0
Jeu_initial.Plq(2).Valeur = 0
Console.ReadLine()
End Sub
End Module
::::::::::::::::::::::::::::::::::::::::::::
Le programme connaît bien l'affectation Jeu_initial.Niv_appel = 6
Par contre, à l'exécution j'ai l'erreur sur la première ligne d'affectation : Jeu_initial.Plq(1).Valeur = 0
erreur : L'exception NullReferenceException n'a pas été gérée, La référence d'objet n'est pas définie à une instance d'un objet.
J'ai l'expérience du C où une structure contenant elle-même des structures en cascade ne pose pas de problème.
Toute aide sera bienvenue, sans m'orienter SVP vers la POO ou autre. Par conviction je veux comprendre ce problème précis. Merci d'avance !!
| EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI Merci d'y penser dans tes prochains messages. |
A voir également:
- Affecter valeur à tableau défini dans une structure (VB.NET)
- Tableau word - Guide
- Tableau ascii - Guide
- Trier un tableau excel - Guide
- Imprimer tableau excel sur une page - Guide
- Les données fournies dans le fichier à télécharger peuvent être synthétisées par le tableau récapitulatif ci-dessous. dans le fichier, générez ce tableau automatiquement (tableau croisé dynamique ou table de pilote) à partir des quatre premières colonnes. il manque 5 valeurs dans le tableau ci-dessous. retrouvez-les dans votre tableau, puis reportez-les arrondies à l’entier le plus proche. - Guide
4 réponses
Il y a quelques différences entre les structures et les classes, entre autre :
- Les structures sont transférées par valeur par défaut contre par référence pour les classes.
- Les structures ne peuvent pas avoir de constructeur par défaut (il faut qu'il soit paramétré et appelé explicitement).
Dans ton cas, il faut soit que tu appelles la méthode Initialize "manuellement" avant de pouvoir utiliser le tableau ou alors l'assigner directement avec un tableau déjà prêt.
- Les structures sont transférées par valeur par défaut contre par référence pour les classes.
- Les structures ne peuvent pas avoir de constructeur par défaut (il faut qu'il soit paramétré et appelé explicitement).
Dans ton cas, il faut soit que tu appelles la méthode Initialize "manuellement" avant de pouvoir utiliser le tableau ou alors l'assigner directement avec un tableau déjà prêt.
Bonjour,
Il te manque quelques lignes ...
K
Il te manque quelques lignes ...
Public Jeu_initial As Jeu = New Jeu
Public Sub Main()
Jeu_initial.Niv_appel = 6
Jeu_initial.Initialize()
Jeu_initial.Plq(1).Valeur = 0
Jeu_initial.Plq(2).Valeur = 0
Console.ReadLine()
End Sub
K
Bonsoir
Comme te l'as expliqué NHenry, c'est justement un problème de pas objet, puisqu'une structure n'est pas un objet.
Il faut comprendre que VB.Net n'est pas un langage orienté objet, mais "tout" objet. La différence est importante, même si complexe à cerner au début.
Exemple, si tu tapes
Un simple 1 dans ton code est déjà un objet de type Integer.
Dans un langage orienté objet ce sera une variable (pas un objet) une fois le code compilé.
Je nuance malgré tout, les types de base, (Integer, bool, double, etc... Attention pas les string) sont basé sur des structures. Ce sont donc des types Valeurs.
A noté que le binding, un des gros points forts de .Net (surtout en WPF), marche mal, voire pas, avec des structures.
J'ai l'expérience du C où une structure contenant elle-même des structures en cascade ne pose pas de problème.
Toute aide sera bienvenue, sans m'orienter SVP vers la POO ou autre.
Comme te l'as expliqué NHenry, c'est justement un problème de pas objet, puisqu'une structure n'est pas un objet.
Il faut comprendre que VB.Net n'est pas un langage orienté objet, mais "tout" objet. La différence est importante, même si complexe à cerner au début.
Exemple, si tu tapes
dim un as string = 1.ToString()Intellisense ne va pas te proposer une liste de méthode quand tu vas tapper le . car il anticipe que tu tapes un double. Mais ça compile et ça marche.
Un simple 1 dans ton code est déjà un objet de type Integer.
Dans un langage orienté objet ce sera une variable (pas un objet) une fois le code compilé.
Je nuance malgré tout, les types de base, (Integer, bool, double, etc... Attention pas les string) sont basé sur des structures. Ce sont donc des types Valeurs.
A noté que le binding, un des gros points forts de .Net (surtout en WPF), marche mal, voire pas, avec des structures.
Bonjour,
Voici une autre façon de faire avec des objets instanciés et non des structures.
A noter qu'au lieu de redimensionner l'objet plaque, j'ai créé une liste fortement typé.
Je te recommande d'éviter d'utiliser des instructions qui se rattache à la référence
Microsoft.VisualBasic
VisualStudio // Explorateur de solution // Clic droit sur projet // Propriétés // Onglets référence
Décoche la référence à Microsoft.VisualBasic
Cela t'éviteras d'utiliser des instructions VB6 (ReDim, CInt, Len, etc ..), toutes ces instructions on leur
équivalent .NET natif.
Dernier point : Il est toujours préférable d'utiliser des IList(Of T) au lieu de List(Of T), le IList est plus
performant au moment d'exécuter des méthodes LinQ sur ces listes.
Un fichier dans le même projet avec les structures qui sont remplacé par des classes (i.e. Objets)
Et le module avec le main :
K
Voici une autre façon de faire avec des objets instanciés et non des structures.
A noter qu'au lieu de redimensionner l'objet plaque, j'ai créé une liste fortement typé.
Je te recommande d'éviter d'utiliser des instructions qui se rattache à la référence
Microsoft.VisualBasic
VisualStudio // Explorateur de solution // Clic droit sur projet // Propriétés // Onglets référence
Décoche la référence à Microsoft.VisualBasic
Cela t'éviteras d'utiliser des instructions VB6 (ReDim, CInt, Len, etc ..), toutes ces instructions on leur
équivalent .NET natif.
Dernier point : Il est toujours préférable d'utiliser des IList(Of T) au lieu de List(Of T), le IList est plus
performant au moment d'exécuter des méthodes LinQ sur ces listes.
Un fichier dans le même projet avec les structures qui sont remplacé par des classes (i.e. Objets)
Public Class Objet_Plaque
#Region "--- Attributs ---"
Private zValeur As UInt32 = 0
#End Region
#Region "--- Propriétés ---"
Public Property Valeur As UInt32
Get
Return Me.zValeur
End Get
Set(value As UInt32)
Me.zValeur = value
End Set
End Property
#End Region
End Class
Public Class Objet_Jeu
#Region "--- Attributs ---"
Private zLsPlq As IList(Of Objet_Plaque) = Nothing
Private zNiv_appel As Int32 = 0
#End Region
#Region "--- Propriétés ---"
Public Property LsPlq As IList(Of Objet_Plaque)
Get
Dim OldPlq As IList(Of Objet_Plaque) = Me.zLsPlq
If (OldPlq Is Nothing) Then
Me.zLsPlq = New List(Of Objet_Plaque)
End If
Return Me.zLsPlq
End Get
Set(value As IList(Of Objet_Plaque))
Me.zLsPlq = value
End Set
End Property
Public Property Niv_appel As Int32
Get
Return Me.zNiv_appel
End Get
Set(value As Int32)
Me.zNiv_appel = value
End Set
End Property
#End Region
End Class
Et le module avec le main :
Public Module DonneesTravail
#Region "--- Attributs ---"
Private zJeu_Initial As Objet_Jeu = Nothing
#End Region
#Region "--- Propriétés ---"
Public Property Jeu_Initial As Objet_Jeu
Get
Dim OldJeu As Objet_Jeu = zJeu_Initial
If (OldJeu Is Nothing) Then
zJeu_Initial = New Objet_Jeu
End If
Return zJeu_Initial
End Get
Set(value As Objet_Jeu)
zJeu_Initial = value
End Set
End Property
#End Region
Public Sub Main()
Dim ObjetPlq As Objet_Plaque = Nothing
With Jeu_Initial
.Niv_appel = 6
.LsPlq = New List(Of Objet_Plaque)
ObjetPlq = New Objet_Plaque
ObjetPlq.Valeur = 0
.LsPlq.Add(ObjetPlq)
ObjetPlq = New Objet_Plaque
ObjetPlq.Valeur = 0
.LsPlq.Add(ObjetPlq)
End With
Console.WriteLine(Jeu_Initial.LsPlq.Count.ToString)
Console.ReadLine()
End Sub
End Module
K