IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Réplication de paramètres entre Classe et Sous Classe (ou conseil de POO) [Débutant]


Sujet :

VB.NET

  1. #1
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut Réplication de paramètres entre Classe et Sous Classe (ou conseil de POO)
    Bonsoir tous le monde,
    J'ai un autre petit soucis avec ma classe qui me sert à gérer les fichiers INI.
    Comme je souhaite bien faire j'ai commencé par décomposer ma classe en plusieurs classes organisées de façon fonctionnel.
    En clair :
    - Classe INI : Classe principale qui contient notamment un Dictionary pour stocker les Sections et les clés quelles contiennent: Dictionary (of String, KeysData).
    - Classe KeysData : Utilisé (ou instancié) par Classe INI et qui contient notamment un Dictionary pour stocker les clés (KeyName, KeyValue).
    - Classe FileINI : utilisé par Classe INI et qui contient notamment une List (of Line) ainsi que les méthodes de lecture/enregistrement du fichier INI .
    - Classe Line : Utilisé par Classe FileINI et qui représente une ligne du fichier INI avec les fonctions de décodage/recodage des lignes de caractères en "Section, Clé, Valeur, Commentaire".

    Jusque là je pense avoir bien fait les choses avec très peu, voir pas du tout de dépendances entre les classes, chacune ayant un rôle bien défini. Cela dit n'hésitait pas à me donner des conseils en POO car je n'ai jamais vraiment maîtrisé le problème.

    Mais le découpage en plusieurs classes me pose aussi quelques problèmes comme celui ci :
    - J'ai besoin d'un paramètre à la fois dans Classe INI et dans Classe Line autrement dit ce paramètre doit être identique à tout moment si je le change dans ClasseINI par exemple y compris dans les objets Line déjà instanciés. Donc forcement si je passe par le New de la Classe Line, ça ne fonctionne pas étant donné que le New ne s’exécute que lors de l'instanciation.
    Je connais un peu les variables partagées "Shared" entre classe mais c'est pour que tous les objets d'une même classe partage la même variable, pas entre classes différentes si je ne dit pas de bêtises.

    Merci beaucoup si vous pouvez m'aider.

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 93
    Points : 127
    Points
    127
    Par défaut
    "J'ai besoin d'un paramètre à la fois dans Classe INI et dans Classe Line autrement dit ce paramètre doit être identique à tout moment"

    Si je résume : INI utilise FileINI qui utilise Line

    Vu ta structure si tu veux passer un élément de INI à Line tu te dois de le passer par FileINI.
    Donc tu peux faire une méthode dans FileINI qui est public qui enverra le paramètre sur son objet List<Line> comme ça puisque INI a accès à FileINI il pourra touché cette méthode.
    Ou alors si c'est une propriété public en lecture et écriture, tu peux directement interagir dessus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fileINI.Lines.Get(1).SetParameter("coucou"); //Admettons que fileINI soit l'instance d'une Classe FileINI
    Une méthode dans Line en public ^^ y a plein de possibilités

  3. #3
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Bonjour,

    En fait je pense qu'il y a un problème de compréhension du problème.

    Si toutes les classes appartiennent les unes aux autres, c'est un "non-sens" de dupliquer une variable, vu qu'elles sont liées.


    Donc la réponse de Kangourex n'est pas si fausse :
    -> si tu veux que la variable appartienne à Line, alors si elle est publique alors elle sera accessible dans la classe la plus haute.
    -> Sinon elle appartient directement à la classe la plus haute.

    Et dans les deux cas on pourra utiliser l'instance de la classe la plus haute pour y accéder à tous les coups.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  4. #4
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci à vous, ça m'a donné quelques idées mais je ne pourrais essayer que ce soir.
    La solution de Kangourex m'à l'air tout à fait fonctionnel mais je m'interroge pour savoir si je peux éviter de parcourir tous les Objets Line.
    Je pense en particulier à un truc comme Shared Parameter1 dans la classe Line mais si j'ai plusieurs instances de INI je ne vais pas pouvoir avoir un Parameter1 propre à un objet INI1 et ses propre objets Line, et un Parameter2 propre à un autre Objet INI2 et ses propre Objets Line.

    Vous en pensez quoi ?
    PS : C'est pas forcement très clair ce que j'ecrits, j’espère que vous comprendrez.

  5. #5
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Essaie de sortir de ton raisonnement.

    Si tu veux une valeur de paramètre commun à INI1 et ses objets Lines, et une valeur à Init2 et ses objets Lines, la réponse est simple :
    La variable doit appartenir à INI et c'est tout !

    Pourquoi la vouloir dans les objets Line ?

    Si tu manipules des lines, se sera à travers un objet INI de toute façon... Donc pas besoin d'aller les mettre dans Lines, ni de les rendre commune aux Line d'un INI... l'instance commune d'instance Line, c'est l'objet INI.

    Edit : Il faudrait peut être que tu expliques à quoi correspondent ces fameux paramètres, la discussion serait moins théoriques
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,

    Citation Envoyé par mactwist69 Voir le message
    La variable doit appartenir à INI et c'est tout !

    Pourquoi la vouloir dans les objets Line ?

    Si tu manipules des lines, se sera à travers un objet INI de toute façon... Donc pas besoin d'aller les mettre dans Lines, ni de les rendre commune aux Line d'un INI... l'instance commune d'instance Line, c'est l'objet INI.
    Je ne suis pas tout à fait d'accord. Ce raisonnement est valable s'il n'a pas besoin de sa variable au niveau d'une instance de Line. Or si j'ai bien compris, il en a besoin. Un objet Line ne connait pas INI mais a besoin d'utiliser une information détenue par INI. A mon sens, le plus simple serait de passer un objet encapsulant ce paramètre (le paramètre serait une propriété de l'objet) depuis INI vers Line via FileIni. Si INI modifie le paramètre, inutile de répercuter cette modification vers Line puisquon manipule la propriété d'un objet (un objet est un pointeur).
    Une autre solution consisterait à passer directement l'instance de INI vers Line mais ... Non !

    Quoi qu'il en soit, il ne faut en aucun cas dupliquer l'information portée par le "paramètre".

    Citation Envoyé par mactwist69 Voir le message
    Edit : Il faudrait peut être que tu expliques à quoi correspondent ces fameux paramètres, la discussion serait moins théoriques
    Complètement d'accord !

  7. #7
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Un objet Line ne connait pas INI mais a besoin d'utiliser une information détenue par INI
    Et bien justement, si Line est une classe et a besoin d'utiliser une variable commune à toutes les Lines dans une méthode...
    C'est que la méthode devrait se trouver dans INI... la classe qui gère l'ensemble de Line + la variable.

    Il est toujours possible d'avoir une méthode dans Line à qui on passerait en paramètre (Byval) cette valeur qu'il aurait besoin ponctuellement pour retourner un résultat.
    Mais on en revient au fait que la variable se trouve dans INI et pas dans toutes les instances de Lines avec exactement la même valeur.

    Ou alors imbriquer les classes ne sert à rien... Autant avoir des objets séparés si il n'y a pas de hiérarchie.


    A moins que Line doit pouvoir exister tout seul de manière autonome, donc DOIT posséder cette valeur...
    mais bon, on verra avec les détails.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  8. #8
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par mactwist69 Voir le message

    Et bien justement, si Line est une classe et a besoin d'utiliser une variable commune à toutes les Lines dans une méthode...
    C'est que la méthode devrait se trouver dans INI... la classe qui gère l'ensemble de Line + la variable.
    Là dessus je suis ok. Mais dans ce cas, il faut passer INI à Line (via FileINI car c'est lui qui crée les instances de Line) pour que Line puisse accéder à la méthode ou la propriété en question.

    Citation Envoyé par mactwist69 Voir le message
    Il est toujours possible d'avoir une méthode dans Line à qui on passerait en paramètre (Byval) cette valeur qu'il aurait besoin ponctuellement pour retourner un résultat.
    A priori, je ne pense pas qu'il s'agisse de cela mais plutôt que Line a besoin de l'info en interne (a voir)

    Citation Envoyé par mactwist69 Voir le message
    Ou alors imbriquer les classes ne sert à rien... Autant avoir des objets séparés si il n'y a pas de hiérarchie.
    A moins que Line doit pouvoir exister tout seul de manière autonome, donc DOIT posséder cette valeur...
    mais bon, on verra avec les détails.
    Ce sont ces détails qui permettront de trancher sur la bonne méthode à employer je pense...

  9. #9
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Je vous remercie de m'aider. Je suis pas encore eut le temps de tout lire dans les détails mais concrètement le paramètre que je veux créer est un boolean que j'appelle OptionSpaceOnSection.
    Ca indique à INI si je dois prendre en compte les espaces (avec un .Trim) dans le nom des sections ou pas vue que c'est dans cette classe que je stocke les Sections (comme indiqué dans mon 1er Post).
    Pour que les comportements des classe soit synchro j'ai également besoin de ce paramètre dans Line vue que c'est là que je recode la ligne de caractères (en tenant compte des caratères clés comme [ ] " = et ;.
    Merci à vous.

  10. #10
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Ok, bon je valide que Line a besoin de la valeur... vu d'ici en tout cas.
    Donc si on repars du besoin, à savoir :

    J'ai besoin d'un paramètre à la fois dans Classe INI et dans Classe Line autrement dit ce paramètre doit être identique à tout moment si je le change dans ClasseINI par exemple y compris dans les objets Line déjà instanciés. Donc forcement si je passe par le New de la Classe Line, ça ne fonctionne pas étant donné que le New ne s’exécute que lors de l'instanciation
    Tu as plusieurs solutions, certaines parmi d'autres :

    1) tu stockes l'unique variable dans INI... mais ta méthode dans Line que tu appel pour écrire te lignes, demande en paramètre cette valeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Me.INIInstance.File(0).WriteMyRows(Me.OptionSpaceOnSection)
    Cette solution ne marche que si l'écriture des lignes passe par la volonté de la classe INI...


    2) Soit tu te fais une propriété dans INI (une propriété Set) qui fera que si tu lui attribue une valeur, tu va boucler sur toutes tes instances Line pour y recopier ta nouvelle valeur (donc dans File, la variable est publique)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Classe INI
     
    Public Property OptionSpaceOnSection as Boolean
         Set (value as Boolean)
               For each _line as Line in Me.MesLine()
                     _line.OptionSpaceOnSection = value
               Next
         End Set
    End Property
     
    End Class
    Donc quand tu feras :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Me.Ini1.OptionSpaceOnSection = True
    La valeur ira en réalité dans toutes ses instances de Line


    Quoiqu'il arrive si tu veux que les instances Line des Ini1 et Ini2 puisse avoir deux valeurs différentes, tu ne peux pas utiliser une variable shared, qui est unique à toutes les instances.

    Sinon, j'imagine qu'il y a des solutions pour faire des pointeurs, des pointeurs de pointeurs... Via les constructeurs, mais je suis pas sur que sur un Boolean se soit possible.... Sinon par l'héritage, pas simple non plus juste pour ça....

    Je laisse place à d'autres idées peut être plus simple
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  11. #11
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    A priori, rien à redire à la réponse de mactwist69. Toutefois, gérer des noms de section nom "trimés", je ne trouve pas ça terrible : Cela implique que deux sections peuvent avoir le même nom à l'espace près avant ou après... Pour ma part, je mettrais systématiquement des trim et me débarasserai de cette option

  12. #12
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci beaucoup, j'ai de quoi lire pour ce soir
    En effet la question du Trim peut se poser, je "paramétrise" beaucoup de choses dans mon code c'est un défaut ou une qualité que j'ai (je ne sait pas). Ce qui est sûre c'est que l'option par défaut sera sans les espaces et je risque avoir 2 ou 3 options de plus (je ne sais pas encore).
    En tout cas je suis vraiment content d'avoir autant d'exemple. Je vous remercie beaucoup.

  13. #13
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Bonsoir,

    @BasicZX81 : tu es conscient qu'en structurant une classe de gestion de cette manière (je parle de stockage des associations clés/valeurs, sections .... dans des variables) qu'il te faudra prévoir l'ajout d’événements de manière à ce qu'à chaque appel de méthode (d'ajout, de suppression, de modification exposée à l'utilisateur de ta classe), les variables de type list ou dictionnary soient mis à jour ?

    Sinon, selon moi :

    ---> il existe dans ta classe des types immuables, je privilégierais donc la mise en place de structures plutôt que des classes.
    ---> plutôt que d'exposer, au futur utilisateur de ta classe, des types de base tel : Dictionary (of String, KeysData) tant que nous sommes dans la POO, je recommanderai de créer une classe qui hérite du type de base mais avec un nom évocateur pour simplifier l'utilisation ainsi tu pourras entrevoir les bénéfices d'une éventuelle implémentation IDisposable.

    Mon avis personnel : je ne pense pas que d'instancier des objets et stocker des valeurs, les supprimer ou les modifier soient une bonne alternative concernant ce type de besoin (gestion de fichier de configuration). A mon sens cela produit trop consommation de ressources pour finalement stocker des données dans un fichier.
    Ce n'est que mon avis personnel mais si cela te permet de travailler la POO alors qu'à cela ne tienne.

    ++ et bon codage.

  14. #14
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Bonsoir Messieurs (Dames ?)
    Voici le code de ma classe, elle commence à être sacrement costaud vue mon niveau.
    D'ailleurs j'ai décider de me laisser quelques jours histoire d'avoir les idées claires sur ce que je veux faire.
    La classe ci-dessous fonctionne, il y a juste un petit bug facilement rectifiable et qui arrive dans certains cas, justement à cause des espaces qui sont pris en compte dans la classe INI mais pas dans la classe Line, et je voulais résoudre ces histoires de passage de paramètres avant de régler cette discordance et aller plus loin.
    Je sais que c'est pas dans les us et coutumes d'écrire du code pour les autres, ce que je comprend tout à fait, mais si vous voulez retoucher le code n’hésitez surtout pas .

    PS: en fouillant un peu dans mes bouts de code à droite à gauche j'ai trouvé 2 méthodes de passages de paramètres entre Form1 et Form 2, je crois que la méthode 1 ressemble à celle de Mactwist69 avec les Property et la méthode 2 n'a pas été evoqué, je serais curieux de savoir ce que vous pensez de cette derniere (la question que je me pose c'est d'un point de vue exécution du nombre de ligne de code ça reviens au mêmes que de parcourir les objets ?)

    Le code de ma classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    '*****************************************************************
    '       Classe INI Version 1.3 par Christian Lamothe
    '*****************************************************************
    '
    '- CREATION DE L'OBJET ET CHARGEMENT DU FICHIER :
    '        INI = New Ini (NomDuFichier)
    '
    '- LIRE UNE CLE :
    '        Valeur = INI.GetKey(of Type)(Section, Clé)
    '
    '- ENREGISTRER UNE CLE :
    '        INI.SetKey(Section, Clé, Valeur) ' Encapsule l'enregistrement avec AutoSave = True
    '
    '
    '
    Imports System
    Imports System.IO
    Imports System.Text
    Imports System.Collections
    Imports System.Text.RegularExpressions
     
    ' Un Objet clsFileINI contient un Dictionary (SectionName as String, KeysData)
    ' chaque objet KeysData contient un Dictionary (Key, Valeur) du type (String, String)
    Public Class INI
    #Region "Déclarations"
        Public Enum NullValueINI
            EmptyKeyAsError
            EmptyKeyAsValue
            IsNull
            IsNotNull
        End Enum
        Private _Sections As New Dictionary(Of String, KeysData)
        Private _CommentSections As New Dictionary(Of String, String)
        'Private _CommentHeadSections As New Dictionary(Of String, String())  ' Non utilisé
        Private _CommentHeadDocument As New List(Of String)
     
        Private _FileName As String
        Private _EncodingText As System.Text.Encoding
        Private _OptionForceDefautEncoding As Boolean = True
        Private _FileINI As FileINI
        Private _AutoSave As Boolean = True
        'Private _ToSave As Boolean
    #End Region
     
    #Region "Constructeurs"
        Public Sub New(ByVal fileName As String, ByVal EncodingText As System.Text.Encoding)
            If fileName = Nothing Or fileName = "" Then Throw New Exception("Un argument 'fileName' n'est pas valide") : Exit Sub
     
            If fileName = Path.GetFileName(fileName) Then
                ' c'est un fichier
                _FileName = Application.StartupPath & "\" & fileName
            Else
                ' c'est un chemin complet
                _FileName = fileName
            End If
            _EncodingText = EncodingText
            _FileINI = New FileINI(fileName, EncodingText)
            Call Load(_FileName, EncodingText)
        End Sub
        ''' <summary>
        ''' Crée une nouvelle instance de IniFile et charge le fichier ini
        ''' </summary>
        ''' <param name="fileName">Chemin du fichier ini</param>
        Public Sub New(ByVal fileName As String)
            Me.New(fileName, System.Text.Encoding.Default)
        End Sub
    #End Region
     
    #Region "Accesseurs"
        ' Elements sections
        Default Property Item(ByVal Section As String) As KeysData
            Get
                If Not _Sections.ContainsKey(Section) Then
                    SetSection(Section)
                End If
     
                Return DirectCast(_Sections(Section), KeysData)
            End Get
            Set(ByVal value As KeysData)
                If Not _Sections.ContainsKey(Section) Then
                    SetSection(Section)
                End If
                _Sections(Section) = value
            End Set
        End Property
    #End Region
     
    #Region "Méthodes"
        Public Sub AddComment(Comment As String)
            If Comment Is Nothing Or Comment = "" Then Exit Sub
            _CommentHeadDocument.Add(Comment)
            '_ToSave = True
            If _AutoSave Then Me.Save()
        End Sub
        Public Sub DeleteAllComment()
            _CommentHeadDocument.Clear()
            '_ToSave = True
            If _AutoSave Then Me.Save()
        End Sub
        ''' <summary>
        ''' Ajoute une section [section] au fichier ini
        ''' </summary>
        ''' <param name="Section">Nom de la section à créer</param>
        Public Sub SetSection(ByVal Section As String)
            'Try
            _SetSection(Section)
            If _AutoSave Then Me.Save()
            'Return True
            'Catch ex As Exception
            'Return False
            'End Try
     
        End Sub
        Public Sub SetSection(ByVal Section As String, Comment As String)
            'Try
            _SetSection(Section, Comment)
            If _AutoSave Then Me.Save()
            'Return True
            'Catch ex As Exception
            'Return False
            'End Try
        End Sub
        Public Sub SetSection(ByVal Section As String, DeleteComment As Boolean)
            'Try
            _SetSection(Section, , DeleteComment)
            If _AutoSave Then Me.Save()
            'Return True
            'Catch ex As Exception
            'Return False
            'End Try
        End Sub
        Private Sub _SetSection(ByVal Section As String, Optional Comment As String = Nothing, Optional DeleteComment As Boolean = False)
            If Section Is Nothing Or Section = "" Then Throw New Exception("Un argument ne peut pas être 'Null'") : Exit Sub
            If Not _Sections.ContainsKey(Section) Then
                _Sections.Add(Section, New KeysData())
            End If
            'If Not Comment Is Nothing And Not _CommentSections.ContainsKey(Section) Then _CommentSections.Add(Section, Comment)
            If Not Comment Is Nothing Then
                If Not _CommentSections.ContainsKey(Section) Then
                    _CommentSections.Add(Section, Comment)
                Else
                    _CommentSections(Section) = Comment
                End If
            End If
            If DeleteComment = True Then
                If _CommentSections.ContainsKey(Section) Then _CommentSections.Remove(Section)
            End If
     
            '_ToSave = True
            'If _AutoSave Then Me.Save()
        End Sub
        ''' <summary>
        ''' Retire une section du fichier
        ''' </summary>
        ''' <param name="Section">Nom de la section à enlever</param>
        Public Sub RemoveSection(ByVal Section As String)
            If Section = Nothing Then Throw New Exception("L'argument 'Section' ne doit pas être 'Null'") : Exit Sub
            If _Sections.ContainsKey(Section) Then
                _Sections.Remove(Section)
                '_ToSave = True
     
            End If
            If _AutoSave Then Me.Save()
        End Sub
        ''' <summary>
        ''' Suprime une clé. Supprime la section si elle est vide.
        ''' </summary>
        ''' <param name="Section">Nom de la section</param>
        ''' <param name="KeyName">Nom de la clef à supprimer</param>
        Public Sub RemoveKey(ByVal Section As String, ByVal KeyName As String)
            If Section = Nothing Or KeyName = Nothing Then Throw New Exception("Un argument ne peut pas être 'Null'") : Exit Sub
     
            Me(Section).DeleteKey(KeyName)
            If Me(Section).Keys.Count = 0 Then
                _Sections.Remove(Section)
                '_ToSave = True
            End If
            If _AutoSave Then Me.Save()
        End Sub
        ''' <summary>
        ''' Modifie ou crée une valeur d'une clef dans une section
        ''' Crée la section si elle n'existe pas
        ''' Crée la clé si elle n'existe pas.
        ''' </summary>
        ''' <param name="section">Nom de la section</param>
        ''' <param name="KeyName">Nom de la clef</param>
        ''' <param name="KeyValue">Valeur de la clef</param>
        Public Function SetKey(Section As String, KeyName As String, KeyValue As Object) As Boolean
            Try
                'Return SetKey(0, Section, KeyName, KeyValue)
                Me(Section).SetKey(KeyName, KeyValue.ToString)
                If _AutoSave Then Me.Save()
                Return True
            Catch ex As Exception
                Return False
            End Try
        End Function
        Public Function SetKey(Section As String, KeyName As String, KeyValue As Object, Comment As String) As Boolean
            Try
                'Return SetKey(1, Section, KeyName, KeyValue, Comment)
                Me(Section).SetKey(KeyName, KeyValue.ToString, Comment)
                If _AutoSave Then Me.Save()
                Return True
            Catch ex As Exception
                Return False
            End Try
        End Function
        Public Function SetKey(Section As String, KeyName As String, KeyValue As Object, DeleteComment As Boolean) As Boolean
            Try
                'Return SetKey(2, Section, KeyName, KeyValue, , DeleteComment)
                Me(Section).SetKey(KeyName, KeyValue.ToString, DeleteComment)
                If _AutoSave Then Me.Save()
                Return True
            Catch ex As Exception
                Return False
            End Try
        End Function
     
        ''' <summary>
        ''' Retourne la valeur d'une clef dans une section
        ''' </summary>
        ''' <param name="Section">Nom de la section</param>
        ''' <param name="KeyName">Nom de la clef</param>
        ''' <returns>Valeur de la clef, ou la valeur entrée par défaut</returns>
        Public Function GetKey(Of T)(ByVal Section As String, ByVal KeyName As String, Optional ByRef NullValue As NullValueINI = NullValueINI.EmptyKeyAsError) As T
            If Section = Nothing Or KeyName = Nothing Then Throw New Exception("Un argument ne peut pas être 'Null'") : Exit Function
            Dim _strValue As Object = Nothing
            Dim _Type As Type = GetType(T)
            Dim _TypeCode As TypeCode = Type.GetTypeCode(GetType(T))
     
            _strValue = Me(Section).GetKey(KeyName)
     
            If _strValue Is Nothing Then
                If NullValue = NullValueINI.EmptyKeyAsError Then
                    Throw New INIExceptionUnableToGetValue("INI Error Exception : Impossible d'obtenir la valeur correspondante à la clé spécifiée : " & KeyName)
                    Exit Function
                Else
                    NullValue = NullValueINI.IsNull
                End If
            Else
                NullValue = NullValueINI.IsNotNull
            End If
     
            Dim _objValue As T = Nothing
            Try
                _objValue = CType(Convert.ChangeType(_strValue, _Type), T)
                '_objValue = CType(_strValue, T)
            Catch ex As Exception
                Throw New INIExceptionUnableToConvertValue("INI Error Exception : La valeur obtenue ne peux pas être convertie vers le type attendue !")
            End Try
            Return _objValue
            'Return _strValue
     
        End Function
        ''' <summary>
        ''' Retourne la valeur d'une clef dans une section
        ''' </summary>
        ''' <param name="Section">Nom de la section</param>
        ''' <param name="KeyName">Nom de la clef</param>
        ''' <param name="defaut">valeur de la clé par défaut</param>
        ''' <returns>Valeur de la clef, ou la valeur entrée par défaut</returns>
        Public Function GetKey(Of T)(ByVal Section As String, ByVal KeyName As String, ByVal defaut As T) As T
            If Section = Nothing Or KeyName = Nothing Then Throw New Exception("Un argument ne peut pas être 'Null'") : Exit Function
            Dim _strValue As Object = Nothing
     
            _strValue = Me(Section).GetKey(KeyName)
            If _strValue Is Nothing Then
                Me(Section).SetKey(KeyName, defaut.ToString)
                If _AutoSave Then Me.Save()
                Return defaut
            Else
                Dim _objValue As T = Nothing
                Try
                    '_objValue = CType(Convert.ChangeType(_strValue, VarType), T)
                    _objValue = CType(_strValue, T)
                Catch ex As Exception
                    Throw New INIExceptionUnableToConvertValue("INI Error Exception : La valeur obtenue ne peux pas être convertie vers le type attendue !")
                End Try
                Return _objValue
            End If
        End Function
    #End Region
     
    #Region "Chargement et Sauvegarde"
        Private Sub Load(ByVal fileName As String, ByVal EncodingText As System.Text.Encoding)
            _FileName = fileName
            _EncodingText = EncodingText
     
            Dim CurrentSection As String = String.Empty
            For Each Line As Line In _FileINI.Lines
                If Line.HasSection Then
                    CurrentSection = Line.SectionName
                    _SetSection(CurrentSection)
                ElseIf Line.HasKey Then
                    'If CurrentSection Is Nothing Or CurrentSection = "" Then Throw New Exception("Section invalide, vérifier si une ligne de commentaire contient le caractére = !") : Exit Sub
                    If Not CurrentSection Is Nothing And Not CurrentSection = "" Then
                        ' La Section est valide, on peut ajouter la clé
                        If Line.HasComment Then
                            Me(CurrentSection).SetKey(Line.KeyName, Line.KeyValue, Line.Comment)
                        Else
                            Me(CurrentSection).SetKey(Line.KeyName, Line.KeyValue)
                        End If
                    Else
                        ' Si la section est invalide on transforme la ligne en ligne de commentaire :
                        _CommentHeadDocument.Add(Line.LineTextIn)
                    End If
                ElseIf Line.HasComment Then
                    _CommentHeadDocument.Add(Line.Comment)
                End If
            Next
     
        End Sub
        ''' <summary>
        ''' Charge un fichier INI
        ''' </summary>
        ''' <param name="fileName">Nom du fichier à charger</param>
        Private Sub Load(ByVal fileName As String)
            Call Load(fileName, _EncodingText)
        End Sub
     
        ''' <summary>
        ''' Sauvegarde le fichier INI en cours
        ''' </summary>
        Public Sub Save()
            If _OptionForceDefautEncoding Then _EncodingText = System.Text.Encoding.Default
            Call SaveAs(_FileName, _EncodingText)
        End Sub
        Public Sub SaveAs(FileName As String)
            _FileName = FileName
            If _OptionForceDefautEncoding Then _EncodingText = System.Text.Encoding.Default
            Call SaveAs(FileName, _EncodingText)
        End Sub
        Public Sub SaveAs(FileName As String, ByVal EncodingText As System.Text.Encoding)
            _FileName = FileName
            _EncodingText = EncodingText
     
            _FileINI.Lines.Clear()
     
            For Each Comment As String In _CommentHeadDocument
                _FileINI.Lines.Add(New Line(Comment))
            Next
     
            For Each Section As String In _Sections.Keys
                If _CommentSections.ContainsKey(Section) Then
                    _FileINI.Lines.Add(New Line(Section, _CommentSections(Section)))
                Else
                    _FileINI.Lines.Add(New Line(Section, ))
                End If
     
                Dim KeysData As KeysData = DirectCast(_Sections(Section), KeysData)
                For Each key As String In (KeysData.Keys)
                    If KeysData.Comment.ContainsKey(key) Then
                        _FileINI.Lines.Add(New Line(key, KeysData(key), KeysData.Comment(key)))
                    Else
                        _FileINI.Lines.Add(New Line(key, KeysData(key), ))
                    End If
                Next
            Next
     
            Try
                _FileINI.Save(FileName, EncodingText)
            Catch ex As Exception
                Throw New System.IO.IOException
            End Try
     
        End Sub
     
    #End Region
     
    #Region "Classe KeysData"
        ' Structure de donnée des clés
        Public Class KeysData
    #Region "Déclarations"
            Private _Keys As New Dictionary(Of String, String)
            Private _CommentKeys As New Dictionary(Of String, String)
    #End Region
     
    #Region "Constructeurs"
            Public Sub New()
     
            End Sub
    #End Region
     
    #Region "Accesseurs"
            ''' <summary>
            ''' Les clefs contenues dans la section
            ''' </summary>
            Public ReadOnly Property Keys() As ICollection
                Get
                    Return _Keys.Keys
                End Get
            End Property
     
            ''' <summary>
            ''' Element Clé
            ''' </summary>
            Default Property Item(ByVal KeyName As String) As String
                Get
                    If _Keys.ContainsKey(KeyName) Then
                        Return _Keys(KeyName).ToString()
                    Else
                        'SetKey(KeyName, "")
                        Return Nothing
                    End If
                End Get
                Set(ByVal value As String)
                    SetKey(KeyName, value)
                End Set
            End Property
            Public ReadOnly Property Comment() As Dictionary(Of String, String)
                Get
                    Return _CommentKeys
                End Get
            End Property
    #End Region
     
    #Region "Méthodes"
            ''' <summary>
            ''' Obtient la valeur d'une clef et léve une exception si elle n'existe pas
            ''' </summary>
            ''' <param name="KeyName">Nom de la clef</param>
            Public Function GetKey(ByVal KeyName As String) As String
                Dim _val As String
                If _Keys.ContainsKey(KeyName) Then
                    ' la clé existe
                    _val = CStr(_Keys(KeyName))
                Else
                    ' La clé n'existe pas
                    _val = Nothing
                End If
                Return _val
            End Function
     
            ''' <summary>
            ''' Affecte une valeur à une clef et la crée si elle n'existe pas
            ''' </summary>
            ''' <param name="KeyName">Nom de la clef</param>
            ''' <param name="KeyValue">Valeur de la clef</param>
            Public Sub SetKey(KeyName As String, KeyValue As String)
                _SetKey(KeyName, KeyValue)
            End Sub
            Public Sub SetKey(KeyName As String, KeyValue As String, Comment As String)
                _SetKey(KeyName, KeyValue)
                If _CommentKeys.ContainsKey(KeyName) Then
                    _CommentKeys(KeyName) = Comment
                Else
                    _CommentKeys.Add(KeyName, Comment)
                End If
            End Sub
            Public Sub SetKey(KeyName As String, KeyValue As String, DeleteComment As Boolean)
                _SetKey(KeyName, KeyValue)
                If DeleteComment And _CommentKeys.ContainsKey(KeyName) Then _CommentKeys.Remove(KeyName)
            End Sub
            Private Sub _SetKey(Keyname As String, KeyValue As String)
                ' Corrigé : KeyName ne peut pas contenir la caratére "="
                If Keyname.Contains("=") Then Throw New Exception("Caractère '=' interdit") : Exit Sub
     
                If _Keys.ContainsKey(Keyname) Then
                    _Keys(Keyname) = KeyValue
                Else
                    _Keys.Add(Keyname, KeyValue)
                End If
            End Sub
     
            ''' <summary>
            ''' Supprime une clefs
            ''' </summary>
            ''' <param name="KeyName">Nom de la clef à supprimer</param>
            Public Sub DeleteKey(ByVal KeyName As String)
                If KeyName = Nothing Then Throw New Exception("Un argument ne peut pas être 'Null'") : Exit Sub
     
                If _Keys.ContainsKey(KeyName) Then _Keys.Remove(KeyName)
                If _CommentKeys.ContainsKey(KeyName) Then _CommentKeys.Remove(KeyName)
            End Sub
    #End Region
     
        End Class
    #End Region
     
    #Region "clsFile"
        Private Class FileINI
    #Region "Déclarations"
            Private _Lines As New List(Of Line)
            Private _sr As StreamReader
            Private _sw As StreamWriter
            'Private _OptionSpacesOnSection As Boolean
    #End Region
     
    #Region "Constructeurs"
            Public Sub New(ByVal fileName As String, ByVal EncodingText As System.Text.Encoding)
                Call Load(fileName, EncodingText)
            End Sub
    #End Region
     
    #Region "Accesseurs"
            ReadOnly Property Lines As List(Of Line)
                Get
                    Lines = _Lines
                End Get
            End Property
            'Public Property OptionSpacesOnSection() As Boolean
            '    Get
            '        Return _OptionSpacesOnSection
            '    End Get
            '    Set(ByVal value As Boolean)
            '        _OptionSpacesOnSection = value
            '        'Call LoadData()
            '    End Set
            'End Property
    #End Region
     
    #Region "Méthodes Public"
            Public Sub Load(ByVal fileName As String, ByVal EncodingText As System.Text.Encoding)
                _sr = New StreamReader(File.Open(fileName, FileMode.OpenOrCreate), EncodingText)
                '' lit chaque ligne du fichier INI
                Dim id As Integer
                While Not _sr.EndOfStream
                    '    'Get current line
                    Dim Line As String = _sr.ReadLine
                    Dim LineData As New Line(Line, INI.Line.LineType.Indefinie)
                    _Lines.Add(LineData)
                    id += 1
                End While
     
                _sr.Close()
            End Sub
            Public Sub Save(ByVal fileName As String, ByVal EncodingText As System.Text.Encoding)
                _sw = New StreamWriter(fileName, False, EncodingText)
                Try
                    For Each LineData As Line In _Lines
                        _sw.Write(LineData.LineTextOut + Environment.NewLine)
                    Next
                    _sw.Flush()
                    _sw.Close()
                Catch ex As Exception
                    Throw New System.IO.IOException
                End Try
            End Sub
     
    #End Region
     
        End Class
    #End Region
     
    #Region "Class clsLine"
        Shadows Class Line
    #Region "Déclarations"
            Private _LineData As LineData
            'Private _LineParameters As LineParameters
            Private _OptionAutorisedSpaceInSection As Boolean = True
            Private _OptionAutorisedSpaceInKeyName As Boolean = True
            Const COM As Char = CChar(";")
            Const CS1 As Char = CChar("[")
            Const CS2 As Char = CChar("]")
            Const EGAL As Char = CChar("=")
            Const DQUOTES As Char = CChar("""")
            Private _rgSection As Regex
            Private _rgSectionAndComment As Regex
            Private _rgKey As Regex
            Private _rgKeyAndComment As Regex
            Private _rgKeyWithQuotes As Regex
            Private _rgKeyWithQuotesAndComment As Regex
            Private _rgComment As Regex
     
            Public Enum LineType
                Indefinie
                Section
                Clé
                Commentaire
            End Enum
     
            Structure LineData
                'Public Id As Integer
                Public LineTextIn As String
                Public LineTextOut As String
                Public HasSection As Boolean
                Public HasKey As Boolean
                Public HasComment As Boolean
                Public SectionName As String
                Public KeyName As String
                Public KeyValue As String
                Public Comment As String
            End Structure
    #End Region
     
    #Region "Constructeurs"
            Public Sub New()
                _LineData = New LineData
     
                Const P1 As String = "(.*)" 'Pattern avec espace
                Const P2 As String = "[\S]+" ' Pattern sans espace
                Dim pS As String 'Pattern Section
                Dim pK As String ' Pattern Key
     
                If _OptionAutorisedSpaceInSection = True Then pS = P1 Else pS = P2
                If _OptionAutorisedSpaceInKeyName = True Then pK = P1 Else pK = P2
     
                _rgSectionAndComment = New Regex(String.Format("(\{1}{0}\{2})([\s]*){3}(.*)", pS, CS1, CS2, COM))
                _rgSection = New Regex(String.Format("\{1}{0}\{2}", pS, CS1, CS2))
                _rgKeyWithQuotesAndComment = New Regex(String.Format("({0})([\s]*){1}([\s]*)(\{2})(.*)(\{2})([\s]*){3}(.*)", pK, EGAL, DQUOTES, COM))
                _rgKeyWithQuotes = New Regex(String.Format("({0})([\s]*){1}([\s]*)(\{2})(.*)(\{2})", pK, EGAL, DQUOTES))   '\x22 = "
                _rgKeyAndComment = New Regex(String.Format("({0})([\s]*){1}([\s]*)(.*)([\s]*){2}(.*)", pK, EGAL, COM))
                _rgKey = New Regex(String.Format("({0})([\s]*){1}([\s]*)(.*)", pK, EGAL))
                _rgComment = New Regex(String.Format("{0}(.*)", COM))
     
            End Sub
            Public Sub New(LineText As String, ByRef LineType As LineType)
                Me.New()
                Call DecodeLine(LineText)
                Call EncodeLine()
            End Sub
            Public Sub New(Section As String, Optional Commentaire As String = Nothing)
                Me.New()
                If Not Section Is Nothing And Not Section = "" Then
                    _LineData.HasSection = True
                    _LineData.SectionName = Section
                End If
                If Not Commentaire Is Nothing And Not Commentaire = "" Then
                    _LineData.HasComment = True
                    _LineData.Comment = Commentaire
                End If
                Call EncodeLine()
            End Sub
            Public Sub New(KeyName As String, KeyValue As String, Optional Commentaire As String = Nothing)
                Me.New()
                If (Not KeyName Is Nothing And Not KeyName = "") And (Not KeyValue Is Nothing And Not KeyValue = "") Then
                    _LineData.HasKey = True
                    _LineData.KeyName = KeyName
                    _LineData.KeyValue = KeyValue
                End If
                If Not Commentaire Is Nothing And Not Commentaire = "" Then
                    _LineData.HasComment = True
                    _LineData.Comment = Commentaire
                End If
                Call EncodeLine()
            End Sub
            Public Sub New(Commentaire As String)
                Me.New()
                If Not Commentaire Is Nothing And Not Commentaire = "" Then
                    _LineData.HasComment = True
                    _LineData.Comment = Commentaire
                End If
                Call EncodeLine()
            End Sub
    #End Region
     
    #Region "Accesseurs"
            ReadOnly Property LineTextIn As String
                Get
                    Return _LineData.LineTextIn
                End Get
            End Property
            ReadOnly Property LineTextOut As String
                Get
                    Return _LineData.LineTextOut
                End Get
            End Property
            ReadOnly Property HasSection As Boolean
                Get
                    Return _LineData.HasSection
                End Get
            End Property
            ReadOnly Property HasKey As Boolean
                Get
                    Return _LineData.HasKey
                End Get
            End Property
            ReadOnly Property HasComment As Boolean
                Get
                    Return _LineData.HasComment
                End Get
            End Property
            Property SectionName As String
                Get
                    Return _LineData.SectionName
                End Get
                Set(value As String)
                    _LineData.SectionName = value
                    Call EncodeLine()
                End Set
            End Property
            Property KeyName As String
                Get
                    Return _LineData.KeyName
                End Get
                Set(value As String)
                    _LineData.KeyName = value
                    Call EncodeLine()
                End Set
            End Property
            Property KeyValue As String
                Get
                    Return _LineData.KeyValue
                End Get
                Set(value As String)
                    _LineData.KeyValue = value
                    Call EncodeLine()
                End Set
            End Property
            Property Comment As String
                Get
                    Return _LineData.Comment
                End Get
                Set(value As String)
                    _LineData.Comment = value
                    Call EncodeLine()
                End Set
            End Property
    #End Region
     
    #Region "Méthodes Privé"
            Private Sub DecodeLine(LineTextIn As String)
                ' Régles d'encodage et de décodage utilisées pour la lecture/Ecriture des fichiers INI :
                '  "KeyName" et "Comment" ne peuvent pas contenir le caratére "="
                '  "KeyValue" peut contenir le caratére "="
                '  "KeyName" et "Comment" peuvent  contenir le caractére ";"
                '  "KeyValue" peut contenir la caratére ";", il est alors borné par des Guillements dans le fichier INI, Ex: "...;...." .
     
                _LineData.LineTextIn = LineTextIn
                Dim mac As MatchCollection
                Debug.Print(String.Format(">>{0}", _LineData.LineTextIn))
     
                If _rgSectionAndComment.IsMatch(LineTextIn) Then
                    _LineData.HasSection = True
                    _LineData.HasComment = True
                    mac = _rgSection.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        Dim Text As String
                        Text = mac(0).Value
                        _LineData.SectionName = mac(0).Value.TrimStart(CS1).TrimEnd(CS2) ' GetSection
     
                        Text = LineTextIn.Remove(0, Text.Length)
     
                        mac = _rgComment.Matches(Text)
                        _LineData.Comment = mac(0).Value.TrimStart(COM).Trim()   ' GetComment
                    End If
                    Debug.Print(String.Format("{1}{0}{2}{0}", "|", _LineData.SectionName, _LineData.Comment))
     
                ElseIf _rgSection.IsMatch(LineTextIn) Then
                    _LineData.HasSection = True
                    mac = _rgSection.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        _LineData.SectionName = mac(0).Value.TrimStart(CS1).TrimEnd(CS2)  ' GetSection
                    End If
                    Debug.Print(String.Format("{1}{0}", "|", _LineData.SectionName))
     
                ElseIf _rgKeyWithQuotesAndComment.IsMatch(LineTextIn) Then
                    _LineData.HasKey = True
                    _LineData.HasComment = True
     
                    mac = _rgKeyWithQuotesAndComment.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        Dim Text As String
                        ' Value peut contenir le carctére ";"
                        Dim rg As New Regex(String.Format("([\s]*)[^\{0}]+(\{0})", EGAL))
                        mac = rg.Matches(LineTextIn)
                        _LineData.KeyName = mac(0).Value.TrimEnd(EGAL).Trim
     
                        Text = LineTextIn.Remove(0, mac(0).Value.Length)
     
                        rg = New Regex(String.Format("([\s]*)(\{0})[^\{0}]+(\{0})", DQUOTES))
                        mac = rg.Matches(Text)
                        _LineData.KeyValue = mac(0).Value.Trim.Trim(DQUOTES)
     
                        Text = Text.Remove(0, mac(0).Value.Length)
     
                        rg = New Regex(String.Format("(\{0})(.*)", COM))
                        mac = rg.Matches(Text)
                        _LineData.Comment = mac(0).Value.TrimStart(COM).Trim    ' GetComment
     
                        Debug.Print(String.Format("{1}{0}{2}{0}{3}{0}", "|", _LineData.KeyName, _LineData.KeyValue, _LineData.Comment))
                    End If
     
                ElseIf _rgKeyWithQuotes.IsMatch(LineTextIn) Then
                    _LineData.HasKey = True
                    mac = _rgKeyWithQuotes.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        Dim Text As String
                        ' Value peut contenir le carctére ";"
                        Dim rg As New Regex(String.Format("([\s]*)[^\{0}]+(\{0})", EGAL))
                        mac = rg.Matches(LineTextIn)
                        _LineData.KeyName = mac(0).Value.TrimEnd(EGAL).Trim
     
                        Text = LineTextIn.Remove(0, mac(0).Value.Length)
     
                        rg = New Regex(String.Format("(\{0})(.*)(\{0})", DQUOTES))
                        mac = rg.Matches(Text)
                        _LineData.KeyValue = mac(0).Value.Trim.Trim(DQUOTES)
     
                        Debug.Print(String.Format("{1}{0}{2}{0}", "|", _LineData.KeyName, _LineData.KeyValue))
                    End If
     
                ElseIf _rgKeyAndComment.IsMatch(LineTextIn) Then
                    _LineData.HasKey = True
                    _LineData.HasComment = True
     
                    mac = _rgKeyAndComment.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        Dim Text As String
                        ' Value ne peut pas contenir le carctére ";"
                        Dim rg As New Regex(String.Format("([\s]*)[^\{0}]+(\{0})", EGAL))
                        mac = rg.Matches(LineTextIn)
                        _LineData.KeyName = mac(0).Value.TrimEnd(EGAL).Trim
     
                        Text = LineTextIn.Remove(0, mac(0).Value.Length)
     
                        rg = New Regex(String.Format("(\{0})[^\{1}]+", EGAL, COM))
                        mac = rg.Matches(LineTextIn)
                        _LineData.KeyValue = mac(0).Value.TrimStart(EGAL).Trim
     
                        rg = New Regex(String.Format("(\{0})(.*)", COM))
                        mac = rg.Matches(Text)
                        _LineData.Comment = mac(0).Value.TrimStart(COM).Trim    ' GetComment
                        Debug.Print(String.Format("{1}{0}{2}{0}{3}{0}", "|", _LineData.KeyName, _LineData.KeyValue, _LineData.Comment))
                    End If
     
                ElseIf _rgKey.IsMatch(LineTextIn) Then
                    _LineData.HasKey = True
                    mac = _rgKey.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        Dim rg As New Regex(String.Format("([\s]*)[^\{0}]+(\{0})", EGAL))
                        mac = rg.Matches(LineTextIn)
                        _LineData.KeyName = mac(0).Value.TrimEnd(EGAL).Trim
     
                        rg = New Regex(String.Format("(\{0})(.*)", EGAL))
                        mac = rg.Matches(LineTextIn)
                        _LineData.KeyValue = mac(0).Value.TrimStart(EGAL).Trim
     
                        Debug.Print(String.Format("{1}{0}{2}{0}", "|", _LineData.KeyName, _LineData.KeyValue))
                    End If
     
                ElseIf _rgComment.IsMatch(LineTextIn) Then
                    _LineData.HasComment = True
                    mac = _rgComment.Matches(LineTextIn)
                    If mac.Count > 0 Then
                        _LineData.Comment = mac(0).Value.TrimStart(COM).Trim() ' GetComment
     
                        Debug.Print(String.Format("{1}{0}", "|", _LineData.Comment))
                    End If
     
                End If
     
            End Sub
            Private Sub EncodeLine()
                _LineData.LineTextOut = EncodeLine(_LineData)
            End Sub
            Private Function EncodeLine(Line As LineData) As String
                Dim LineText As String = String.Empty
     
                If Line.HasSection Then
                    LineText = String.Format("{1}{0}{2}", Line.SectionName.Trim, CS1, CS2)
                ElseIf Line.HasKey Then
                    If Line.KeyValue.Contains(COM) Then
                        LineText = String.Format("{0} {2} {3}{1}{3}", Line.KeyName.Trim, Line.KeyValue.Trim, EGAL, DQUOTES)
                    Else
                        LineText = String.Format("{0} {2} {1}", Line.KeyName.Trim, Line.KeyValue.Trim, EGAL)
                    End If
                End If
     
                If Line.HasComment Then
                    Dim IndentComment As Integer  ' + Int(1 + StringLine.Length / 10) * 10
                    If Line.HasSection Then
                        IndentComment = 50
                    ElseIf Line.HasKey Then
                        IndentComment = 50
                    Else
                        IndentComment = 0
                    End If
                    If LineText.Length >= IndentComment Then IndentComment = LineText.Length
                    Dim Espace As Integer = IndentComment - LineText.Length
                    'Dim Tab As Integer = Int(Espace / 4) ' 1 Tab=4 espace
                    'StringLine += New String(ControlChars.Tab, 2) & " ; " & LineData.Comment
                    'LineText += New String(" ", Espace) & " ; " & Line.Comment
                    LineText += String.Format("{0} {1} {2}", New String(CChar(" "), Espace), COM, Line.Comment)
                End If
     
                Return LineText
            End Function
            Private Function xCode(c As Char) As String
                Dim u As Short = Convert.ToInt16(c) ' Convertie un caractéres Unicode
                'Dim h As UInt32 = Convert.ToInt32(u, 16)
                Dim h As String = u.ToString("X")
                xCode = "x" & h.ToString
                Return xCode
            End Function
    #End Region
        End Class
        'Public Class LineParameters
        '    Event ValueChanged(ByVal PropertyName As String, ByVal Value As Object)
        '    Private _Param1 As String
        '    Public Property Param1() As String
        '        Get
        '            Return _Param1
        '        End Get
        '        Set(ByVal value As String)
        '            _Param1 = value
        '            RaiseEvent ValueChanged("Param1", value)
        '        End Set
        '    End Property
     
        'End Class
    #End Region
     
    End Class
     
    #Region "Exceptions personnalisées"
    Class INIExceptionUnableToGetValue
        Inherits System.ApplicationException
        Public Sub New()
     
        End Sub
        Public Sub New(ByVal message As String)
            MyBase.New(message)
        End Sub
        Public Sub New(ByVal message As String, ByVal inner As Exception)
            MyBase.New(message, inner)
        End Sub
    End Class
     
    Class INIExceptionUnableToConvertValue
        Inherits System.ApplicationException
        Public Sub New()
     
        End Sub
        Public Sub New(ByVal message As String)
            MyBase.New(message)
        End Sub
        Public Sub New(ByVal message As String, ByVal inner As Exception)
            MyBase.New(message, inner)
        End Sub
    End Class
    #End Region
    Petit tests de passage de paramètres entre Form1 et Form2 suivant 2 méthodes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    Public Class Params
        Event ValueChanged(ByVal PropertyName As String, ByVal Value As Object)
        Private _Param1 As String
        Public Property Param1() As String
            Get
                Return _Param1
            End Get
            Set(ByVal value As String)
                _Param1 = value
                RaiseEvent ValueChanged("Param1", value)
            End Set
        End Property
     
    End Class
     
    Public Class Form1
        ' Méthode 2
        Private Param As New Params
        Public MaForm2 As Form2
        Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
            ' Méthode 2
            MaForm2 = New Form2(Param)
            AddHandler Param.ValueChanged, AddressOf RefreshData
        End Sub
        ' Méthode 2
        Private Sub RefreshData(ByVal PropertyName As String, Value As Object)
            Debug.Print("(Méthode 2) La valeur dans Form1 a changé : " & PropertyName & " a changé : " & Value.ToString)
        End Sub
        ' Méthode 1
        Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
            MaForm2.Paramètre = TextBox1.Text
        End Sub
        ' Méthode 2
        Private Sub TextBox2_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox2.TextChanged
            Param.Param1 = TextBox2.Text
        End Sub
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles ButtonShoxForm2.Click
     
            MaForm2.Show()
        End Sub
    End Class
     
    Public Class Form2
        ' Méthode 1
        Private _Paramètre As String
        ' Méthode 2
        Private _Param As Params
     
        Public Sub New()
     
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
        End Sub
     
        'Méthode 2
        Public Sub New(ByRef Param As Params)
            Call Me.New()
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            _Param = Param
        End Sub
     
        ' Méthode 1
        Public Property Paramètre() As String
            Get
                Return _Paramètre
            End Get
            Set(ByVal value As String)
                _Paramètre = value
                Call LoadData()
            End Set
        End Property
     
        Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Me.Hide()
            e.Cancel = True
        End Sub
     
        Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            AddHandler _Param.ValueChanged, AddressOf RefreshData
            ' Call LoadData()
            ' Call Refresh()
        End Sub
        ' Méthode 1
        Private Sub LoadData()
            TextBoxParamètre.Text = _Paramètre
        End Sub
        ' Méthode 2
        Private Sub RefreshData(ByVal PropertyName As String, Value As Object)
            Debug.Print("(Méthode 2) La valeur dans Form2 a changé : " & PropertyName & " a changé : " & Value.ToString)
            TextBoxParamètre.Text = _Param.Param1
        End Sub
     
    End Class
    EDIT : avec le projet complet c'est encore mieux :
    Pièce jointe 187445

  15. #15
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Etant donné que mes premières impressions ne suscitent pas de réactions, et que tout conseil est bon à prendre je me lance une seconde fois :

    ---> en voyant finalement le code on se rends bien compte qu'il y a un truc que tu as loupés concernant la retranscription en POO :

    Une classe de gestion complète de fichier par définition permet l'accès en lecture et en écriture, ce sont à mon sens 2 principes sur lesquels tu devrais appuyer la réflexion sur la conception de ta classe. Cela éviterait de te retrouver avec des méthodes SetKey et GetKey ou je ne sais encore.....

    Question lisibilité de ton projet :

    L'organisation par #régions c'est bien, mais ce qui est encore mieux et cela est valable avant même de coder quoique ce soit c'est d'etendre les classes au sein d'un espace de noms. Ainsi tu appréhenderas plus facilement :

    - ce qui ressort de la réflexion
    - ce qui nécessite des ajustements

    ...ensuite seulement on se concentre sur la refacto et l'optimisation du code.

    ++

  16. #16
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    @Wallace1 : Je ne réagit pas à tout simplement parceque je ne comprends pas forcement tout mais par contre je lit tout ne serait ce par respect de ce qui font l'effort de me répondre
    Il faut juste pas perdre de vue que je code depuis un certain temps certes mais sans aucune formation, sans aucune règles de bonnes pratiques, il y à des termes que je ne comprends pas du tout comme les "une classe qui herite de types de base" ou "Idisposable" donc forcement ça aide pas

    Pour en revenir à SetKey et GetKey il faut bien à un moment ou à un autre exposer des méthodes pour permettre ces opérations dans le code principal, comment pourrais-je faire autrement ?

  17. #17
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par BasicZX81 Voir le message
    @Wallace1 : Je ne réagit pas à tout simplement parceque je ne comprends pas forcement tout mais par contre je lit tout ne serait ce par respect de ce qui font l'effort de me répondre
    Et c'est tout à ton honneur.

    Citation Envoyé par BasicZX81 Voir le message
    Il faut juste pas perdre de vue que je code depuis un certain temps certes mais sans aucune formation, sans aucune règles de bonnes pratiques,.....
    Il ne faut pas croire que tu es seul dans ce cas, pour la plupart nous n'avons pas suivi de cursus scolaire dans cette branche et pour d'autres nous nous sommes découvert cette passion que très ou trop tardivement.....

    Citation Envoyé par BasicZX81 Voir le message
    ...... il y à des termes que je ne comprends pas du tout comme les "une classe qui herite de types de base" ou "Idisposable" donc forcement ça aide pas
    Pourquoi ne pas poser la question..... ???? Il faut aussi s'impliquer en faisant quelques recherche (MSDN) car j'ai envie de croire que ce qui nous caractérise tous en programmation c'est la curiosité !

    Citation Envoyé par BasicZX81 Voir le message
    Pour en revenir à SetKey et GetKey il faut bien à un moment ou à un autre exposer des méthodes pour permettre ces opérations dans le code principal, comment pourrais-je faire autrement ?
    Si tu exposais une propriété de type Key alors le getter et le setter ferait très bien l'affaire

    Mais avant cela il faudrait vraiment songer à repenser la gestion et découper ton projet pour faire ressortir une classe IniReader et IniWriter puis ensuite tu pourrais éventuellement revoir la manière dont tu gères tes sections (une classe SectionsCollection), tes associations clés/valeurs au sein d'une classe (SectionBody)....;etc....

    Le tout c'est de bien décomposer avec un minimum de pertinence selon le dictionnaire de données (lors de l'analyse conceptuelle).

    ++

  18. #18
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Merci pour les réponses Wallace1.
    Si tu exposais une propriété de type Key alors le getter et le setter ferait très bien l'affaire
    En effet, Je n'y avait pas penser. C'est là que je vois qu'il me manque clairement de l'expérience, j'entrevois certaines façon de faire mais je ne sais pas dire si tel ou tel façon de faire est mieux ou pas....

    Mais avant cela il faudrait vraiment songer à repenser la gestion et découper ton projet pour faire ressortir une classe IniReader et IniWriter puis ensuite tu pourrais éventuellement revoir la manière dont tu gères tes sections (une classe SectionsCollection), tes associations clés/valeurs au sein d'une classe (SectionBody)....;etc....
    Pareil, manque d'expérience..... Pourtant j'ai réfléchie à ma façon de d'organiser mes classes mais même là en lisant je ne vois pas ce qu'apporte le découpage en IniReader et IniWriter.....Attention je ne dis pas que cette solution n'est pas viable, c'est juste que je n'aurais jamais songé à ça....Je commence à désespérer d'arriver un jour à écrire une bonne classe....

    Le tout c'est de bien décomposer avec un minimum de pertinence selon le dictionnaire de données (lors de l'analyse conceptuelle).
    Bon je ne vais pas me mentir hein, l'analyse conceptuelle c'est un peu comme je le sents par rapport à ma propre expérience sans critères ni règles précise si ce n'est d’éviter de mélanger les fonctions et éviter les couplages (je crois que c'est comme ça qu'on dit)....

    Bon on va essayer d'y croire quand même, y'a du boulot....

  19. #19
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par BasicZX81 Voir le message
    ...... mais même là en lisant je ne vois pas ce qu'apporte le découpage en IniReader et IniWriter.....
    En fait il faut savoir que le fait de découper un problème permet d'y voir plus clair lors de la conception d'un projet et de ce fait il ressort un dictionnaire de données qui permet d'identifier d'éventuels noms de classes et attributs.


    Je commence à désespérer d'arriver un jour à écrire une bonne classe.
    La persévérance fait aussi partie des qualités d'un développeur.

    Citation Envoyé par BasicZX81 Voir le message
    Bon je ne vais pas me mentir hein, l'analyse conceptuelle c'est un peu comme je le sents par rapport à ma propre expérience sans critères ni règles précise si ce n'est d’éviter de mélanger les fonctions et éviter les couplages (je crois que c'est comme ça qu'on dit)....

    Bon on va essayer d'y croire quand même, y'a du boulot....
    Il existe des méthodologies pour la conception de projets de développement, ce n'est pas anodin : gain de temps lors du codage et le découpage en plusieurs petits projets permet la réutilisation : tous mes projets contiennent à 80% des classes que je réutilise et/ou agrémente dans d'autres projets : ça prouve qu'en passant du temps à l'étude sur un projet on gagne du temps dans les futurs projets.

    Couplage wtF lol. Je dirai surtout d eviter le code redondant mais c'est lors de l optimisation qu on s occupe de ca

    Allez bon courage et si tu veux des conseils saches que je reste à ton écoute.

  20. #20
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Points : 372
    Points
    372
    Par défaut
    Heu, vous n'auriez pas une classe bien écrite par hasard ? qui respecte des règles de POO dont je pourrais m'inspirer ?
    Une classe qui gère les fichiers INI par exemple ? . J'en ai déja trouvé sur le Net mais je suis toujours revenue sur des solutions à moi que je comprends et que je peux facilement modifier ou adapter à mes besoins et aussi parce que je n'ai pas un niveau assez bon pour juger de la qualité au niveau de l'organisation/découpage de la classe.
    Mais si je trouve un bon modèle ça doit pouvoir s'adapter facilement à mes besoins tout en me permettant de comprendre pourquoi c'est mieux.....
    En tout cas merci beaucoup.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 4
    Dernier message: 03/09/2010, 16h52
  2. Réponses: 2
    Dernier message: 25/12/2008, 21h51
  3. [Reflection] Obtenir les sous-classes d'une classe
    Par El Saigneur dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 11/06/2007, 08h14
  4. [POO] Organiser ses classes (en sous classes)
    Par alexfrere dans le forum Langage
    Réponses: 5
    Dernier message: 20/03/2007, 14h07
  5. Super classes et sous-classes/Méthodes
    Par smag dans le forum Langage
    Réponses: 4
    Dernier message: 30/06/2005, 00h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo