Les structures en C sharp

 La structure C# est analogue à la structure du langage C et est très proche de la notion de classe. Une structure est définie comme
suit :
struct NomStructure{
// attributs
...
// propriétés
...
// constructeurs
...
// méthodes
...
}
Il y a, malgré une similitude de déclaration des différences importantes entre classe et structure. La notion d'héritage n'existe par
exemple pas avec les structures. Si on écrit une classe qui ne doit pas être dérivée, quelles sont les différences entre structure et
classe qui vont nous aider à choisir entre les deux ? Aidons-nous de l'exemple suivant pour le découvrir :
1. using System;
2.
3. namespace Chap2 {
4. class Program1 {
5. static void Main(string[] args) {
6. // une structure sp1
7. SPersonne sp1;
8. sp1.Nom = "paul";
9. sp1.Age = 10;
10. Console.WriteLine("sp1=SPersonne(" + sp1.Nom + "," + sp1.Age + ")");
11. // une structure sp2
12. SPersonne sp2 = sp1;
13. Console.WriteLine("sp2=SPersonne(" + sp2.Nom + "," + sp2.Age + ")");
14. // sp2 est modifié
15. sp2.Nom = "nicole";
16. sp2.Age = 30;
17. // vérification sp1 et sp2
18. Console.WriteLine("sp1=SPersonne(" + sp1.Nom + "," + sp1.Age + ")");
19. Console.WriteLine("sp2=SPersonne(" + sp2.Nom + "," + sp2.Age + ")");
20.
21. // un objet op1
22. CPersonne op1=new CPersonne();
23. op1.Nom = "paul";
24. op1.Age = 10;
25. Console.WriteLine("op1=CPersonne(" + op1.Nom + "," + op1.Age + ")");
26. // un objet op2
27. CPersonne op2=op1;
28. Console.WriteLine("op2=CPersonne(" + op2.Nom + "," + op2.Age + ")");
29. // op2 est modifié
30. op2.Nom = "nicole";
31. op2.Age = 30;
32. // vérification op1 et op2
33. Console.WriteLine("op1=CPersonne(" + op1.Nom + "," + op1.Age + ")");
34. Console.WriteLine("op2=CPersonne(" + op2.Nom + "," + op2.Age + ")");
35. }
36. }
37. // structure SPersonne
38. struct SPersonne {
39. public string Nom;
40. public int Age;
41. }
42.
43. // classe CPersonne
44. class CPersonne {
45. public string Nom;
46. public int Age;
47. }
48.
49.}
• lignes 38-41 : une structure avec deux champs publics : Nom, Age
• lignes 44-47 : une classe avec deux champs publics : Nom, Age
Si on exécute ce programme, on obtient les résultats suivants :
1. sp1=SPersonne(paul,10)
2. sp2=SPersonne(paul,10)
3. sp1=SPersonne(paul,10)
4. sp2=SPersonne(nicole,30)
5. op1=CPersonne(paul,10)
6. op2=CPersonne(paul,10)
7. op1=CPersonne(nicole,30)
8. op2=CPersonne(nicole,30)
Là où précédemment on utilisait une classe Personne, nous utilisons maintenant une structure SPersonne :
une structure SPersonne
une structure SPersonne
 La structure n'a ici pas de constructeur. Elle pourrait en avoir un comme nous le montrerons plus loin. Par défaut, elle dispose
toujours du constructeur sans paramètres, ici  SPersonne().
• ligne 7 du code : la déclaration
SPersonne sp1;
est équivalente à l'instruction :
SPersonne sp1=new Spersonne();
Une structure (Nom,Age) est créée et la valeur de sp1 est cette structure elle-même. Dans le cas de la classe, la création
de l'objet (Nom,Age) doit se faire explicitement par l'opérateur new (ligne 22) :
CPersonne op1=new CPersonne();
L'instruction précédente crée un objet CPersonne (grosso modo l'équivalent de notre structure) et la valeur de p1 est alors
l'adresse (la référence) de cet objet.
Résumons
 dans le cas de la structure, la valeur de sp1 est la structure elle-même
 dans le cas de la classe, la valeur de op1 est l'adresse de l'objet créé
Lorsque dans  le programme on écrit ligne 12 :
SPersonne sp2 = sp1;
une nouvelle structure sp2(Nom,Age) est créée et initialisée avec la valeur de sp1, donc la structure elle-même.

nouvelle structure sp2(Nom,Age)
nouvelle structure sp2(Nom,Age)


 La structure de sp1 est dupliquée dans sp2 [1]. C'est une recopie de valeur. Considérons maintenant l'instruction, ligne 27 :
CPersonne op2=op1;
Dans le cas des classes, la valeur de op1 est recopiée dans op2, mais comme cette valeur est en fait l'adresse de l'objet, celui-ci n'est
pas dupliqué [2].
Dans le cas de la structure [1], si on modifie la valeur de sp2 on ne modifie pas la valeur de sp1, ce que montre le programme. Dans
le cas de l'objet [2], si on modifie l'objet pointé par  op2, celui pointé par  op1  est modifié puisque c'est le même. C'est ce que
montrent également les résultats du programme.
On retiendra donc de ces explications que :
 la valeur d'une variable de type structure est la structure elle-même
 la valeur d'une variable de type objet est l'adresse de l'objet pointé
Une fois cette différence fondamentale comprise, la structure se montre très proche de la classe comme le montre le nouvel
exemple suivant :
1. using System;
2.
3. namespace Chap2 {
4.
5. // structure SPersonne
6. struct SPersonne {
7. // attributs privés
8. private string nom;
9. private int age;
10.
11. // propriétés
12. public string Nom {
13. get { return nom; }

14. set { nom = value; }
15. }//nom
16.
17. public int Age {
18. get { return age; }
19. set { age = value; }
20. }//age
21.
22. // Constructeur
23. public SPersonne(string nom, int age) {
24. this.nom = nom;
25. this.age = age;
26. }//constructeur
27.
28. // ToString
29. public override string ToString() {
30. return "SPersonne(" + Nom + "," + Age + ")";
31. }//ToString
32. }//structure
33.}//namespace
• lignes 8-9 : deux champs privés
• lignes 12-20 : les propriétés publiques associées
• lignes 23-26 : on définit un constructeur. A noter que le constructeur sans paramètres SPersonne() est toujours présent et
n'a pas à être déclaré. Sa déclaration est refusée par le compilateur. Dans le constructeur des lignes 23-26, on pourrait être
tenté d'initialiser les champs privés nom, age via leurs propriétés publiques Nom, Age. C'est refusé par le compilateur. Les
méthodes de la structure ne peuvent être utilisées lors de la construction de celle-ci.
lignes 29-31 : redéfinition de la méthode ToString.

Un programme de test pourrait être le suivant :
1. using System;
2.
3. namespace Chap2 {
4. class Program1 {
5. static void Main(string[] args) {
6. // une personne p1
7. SPersonne p1=new SPersonne();
8. p1.Nom="paul";
9. p1.Age= 10;
10. Console.WriteLine("p1={0}",p1);
11. // une personne p2
12. SPersonne p2 = p1;
13. Console.WriteLine("p2=" + p2);
14. // p2 est modifié
15. p2.Nom = "nicole";
16. p2.Age = 30;
17. // vérification p1 et p2
18. Console.WriteLine("p1=" + p1);
19. Console.WriteLine("p2=" + p2);
20. // une personne p3
21. SPersonne p3 = new SPersonne("amandin", 18);
22. Console.WriteLine("p3=" + p3);
23. // une personne p4
24. SPersonne p4 = new SPersonne { Nom = "x", Age = 10 };
25. Console.WriteLine("p4=" + p4);
26. }
27. }
28.}
• ligne 7 : on est obligés d'utiliser explicitement le constructeur sans paramètres, ceci parce qu'il existe un autre constructeur
dans la structure. Si la structure n'avait eu aucun constructeur, l'instruction
SPersonne p1;

aurait suffi pour créer une structure vide.
• lignes 8-9 : la structure est initialisée via ses propriétés publiques
• ligne 10 : la méthode p1.ToString va être utilisée dans le WriteLine.
• ligne 21 : création d'une structure avec le constructeur SPersonne(string,int)
• ligne 24 :  création d'une structure avec le constructeur sans paramètres SPersonne() avec, entre accolades, initialisation des
champs privés via leurs propriétés publiques.

On obtient les résultats d'exécution suivants :
1. p1=SPersonne(paul,10)
2. p2=SPersonne(paul,10)
3. p1=SPersonne(paul,10)
4. p2=SPersonne(nicole,30)
5. p3=SPersonne(amandin,18)
6. p4=SPersonne(x,10)
La seule différence notable ici entre structure et classe, c'est qu'avec une classe les objets p1 et p2 auraient pointé sur le même objet  à la fin du programme.

Publié par Drupal french Study