Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Une définition de classe ou de struct est semblable à un blueprint qui spécifie ce que le type peut faire. Un objet est un bloc de mémoire que le programme alloue et configure en fonction du blueprint. Un programme peut créer de nombreux objets de la même classe. Vous pouvez également appeler des instances d’objets. Vous pouvez les stocker dans une variable nommée ou dans un tableau ou une collection. Le code client utilise ces variables pour appeler les méthodes et accéder aux propriétés publiques de l’objet. Dans un langage orienté objet tel que C#, un programme classique se compose de plusieurs objets qui interagissent dynamiquement.
Remarque
Les types statiques se comportent différemment de ce qui est décrit dans cet article. Pour plus d’informations, consultez la page Classes statiques et membres de classes statiques.
Instances de struct et instances de classe
Étant donné que les classes sont des types de référence, une variable d’un objet de classe contient une référence à l’adresse de l’objet sur le tas managé. Si vous attribuez une deuxième variable du même type à la première variable, les deux variables font référence à l’objet à cette adresse. Cet article décrit ce point plus en détail plus loin.
Vous créez des instances de classes à l’aide de l’opérateurnew. Dans l’exemple suivant, Person est le type et person1 et person2 sont des instances ou des objets de ce type.
using System;
public class Person(string name, int age)
{
public string Name { get; set; } = name;
public int Age { get; set; } = age;
// Other properties, methods, events...
}
class Program
{
static void Main()
{
Person person1 = new("Leopold", 6);
Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
// Declare new person, assign person1 to it.
Person person2 = person1;
// Change the name of person2, and person1 also changes.
person2.Name = "Molly";
person2.Age = 16;
Console.WriteLine($"person2 Name = {person2.Name} Age = {person2.Age}");
Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
/*
Output:
person1 Name = Leopold Age = 6
person2 Name = Molly Age = 16
person1 Name = Molly Age = 16
*/
}
}
Étant donné que les structs sont des types valeur, une variable d’un objet struct contient une copie de l’objet entier. Vous pouvez également créer des instances de structs à l’aide de l’opérateur new , mais vous n’avez pas besoin de l’utiliser, comme illustré dans l’exemple suivant :
using System;
namespace Example
{
public struct Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
public class Application
{
static void Main()
{
// Create struct instance and initialize by using "new".
// Memory is allocated on thread stack.
Person p1 = new("Alex", 9);
Console.WriteLine($"p1 Name = {p1.Name} Age = {p1.Age}");
// Create new struct object. Note that struct can be initialized
// without using "new".
Person p2 = p1;
// Assign values to p2 members.
p2.Name = "Spencer";
p2.Age = 7;
Console.WriteLine($"p2 Name = {p2.Name} Age = {p2.Age}");
// p1 values remain unchanged because p2 is copy.
Console.WriteLine($"p1 Name = {p1.Name} Age = {p1.Age}");
}
}
/*
Output:
p1 Name = Alex Age = 9
p2 Name = Spencer Age = 7
p1 Name = Alex Age = 9
*/
}
La pile du thread alloue de la mémoire à la fois pour p1 et pour p2. Le programme récupère cette mémoire en fonction du type ou de la méthode avec lesquels vous la déclarez. Cette gestion de la mémoire est l’une des raisons pour lesquelles les structures sont copiées lors d’une affectation. En revanche, le Common Language Runtime libère automatiquement la mémoire qu’il alloue pour une instance d’une classe lorsque toutes les références à l’objet sortent de la portée. Vous ne pouvez pas détruire de façon déterministe un objet de classe comme vous pouvez en C++. Pour plus d’informations sur l’opération de garbage collection dans .NET, consultez Garbage Collection.
Remarque
Le Common Language Runtime optimise fortement l’allocation et la désallocation de la mémoire sur le tas managé. Dans la plupart des cas, il n’existe aucune différence significative en termes de performance entre l’allocation d’une instance de classe sur le tas et l’allocation d’une instance de structure sur la pile.
Identité d’objet et égalité des valeurs
Lorsque vous comparez deux objets pour l’égalité, déterminez d’abord si les deux variables représentent le même objet en mémoire ou si les valeurs d’un ou plusieurs de leurs champs sont équivalentes. Si vous souhaitez comparer des valeurs, déterminez si les objets sont des instances de types valeur (structs) ou des types référence (classes, délégués, tableaux).
Utilisez la méthode statique Object.ReferenceEquals pour déterminer si deux instances de classe font référence au même emplacement en mémoire (ce qui signifie qu’elles ont la même identité). (System.Object est la classe de base implicite pour tous les types valeur et types de référence, y compris les structs et classes définis par l’utilisateur.)
Par défaut, la ValueType.Equals méthode détermine si les champs d’instance dans deux instances de struct ont les mêmes valeurs. Étant donné que tous les structs héritent implicitement de System.ValueType, vous appelez la méthode directement sur votre objet, comme indiqué dans l’exemple suivant :
// Person is defined in the previous example. //public struct Person(string name, int age) //{ // public string Name { get; set; } = name; // public int Age { get; set; } = age; //} Person p1 = new("Wallace", 75); Person p2 = new("", 42); p2.Name = "Wallace"; p2.Age = 75; if (p2.Equals(p1)) Console.WriteLine("p2 and p1 have the same values."); // Output: p2 and p1 have the same values.L'implémentation par défaut de System.ValueType utilise le boxing et la réflexion dans certains cas. Pour plus d’informations sur la façon de fournir un algorithme d’égalité efficace spécifique à votre type, consultez Implémenter l’égalité vous-même lorsqu’un type ne peut pas être un enregistrement. Les enregistrements sont des types de référence qui utilisent la sémantique de valeur pour l’égalité.
Pour déterminer si les valeurs des champs dans deux instances de classe sont égales, vous pouvez utiliser la méthode Equals ou l’opérateur ==. Toutefois, utilisez-les uniquement si la classe les a substitués ou surchargés pour fournir une définition personnalisée de ce que signifie « égalité » pour les objets de ce type. La classe peut également implémenter l’interface IEquatable<T> ou l’interface IEqualityComparer<T>. Les deux interfaces fournissent des méthodes qui peuvent être utilisées pour tester l’égalité des valeurs. Lors de la conception de vos propres classes qui remplacent
Equals, veillez à suivre les instructions indiquées dans Implémenter l’égalité vous-même lorsqu’un type ne peut pas être un enregistrement et Object.Equals(Object).
Sections connexes
Pour en savoir plus, consultez :