Objets (Guide de programmation C#)
Une définition de classe ou de struct ressemble à un plan qui spécifie ce que le type peut faire. Un objet est fondamentalement un bloc de mémoire qui a été alloué et configuré en fonction du plan. Un programme peut créer de nombreux objets de la même classe. Les objets sont également appelés instances, et ils peuvent être stockés dans une variable nommée, dans un tableau ou dans une collection. Le code client est le code qui 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.
Notes
Les types statiques se comportent différemment de ce qui est décrit ici.Pour plus d’informations, consultez Classes statiques et membres de classe statique (Guide de programmation C#).
Instances de struct VS. des instances de classe
Parce que les classes sont des types référence, une variable d'objet de classe maintient une référence à l'adresse de l'objet sur le tas managé. Si un deuxième objet du même type est assigné au premier objet, les deux variables font référence à l'objet à cette adresse. Ce point est abordé plus en détail ultérieurement dans cette rubrique.
Les instances de classes sont créées à l'aide du nouvel opérateur. Dans l'exemple suivant, Person est le type et person1 et person 2 sont des instances, ou objets, de ce type.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
//Other properties, methods, events...
}
class Program
{
static void Main()
{
Person person1 = new Person("Leopold", 6);
Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, 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 = {0} Age = {1}", person2.Name, person2.Age);
Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Output:
person1 Name = Leopold Age = 6
person2 Name = Molly Age = 16
person1 Name = Molly Age = 16
*/
Parce que les structs sont des types valeur, une variable d'objet de struct conserve une copie de l'objet entier. Les instances de structs peuvent également être créées à l'aide de l'opérateur new, mais cela n'est pas obligatoire, comme illustré dans l'exemple suivant :
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 Person("Alex", 9);
Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, 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 = {0} Age = {1}", p2.Name, p2.Age);
// p1 values remain unchanged because p2 is copy.
Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
Output:
p1 Name = Alex Age = 9
p2 Name = Spencer Age = 7
p1 Name = Alex Age = 9
*/
La mémoire pour p1 et p2 est allouée sur la pile des threads. Cette mémoire est récupérée avec le type ou la méthode dans laquelle elle est déclarée. C'est l'une des raisons pour lesquelles les structs sont copiés lors de l'assignation. Par contraste, la mémoire allouée pour une instance de classe est récupérée automatiquement (par le garbage collector) par le Common Language Runtime lorsque toutes les références à l'objet sont sorties de la portée. Il n'est pas possible de détruire de façon déterministe un objet de classe comme cela est possible en C++. Pour plus d'informations sur le garbage collection dans .NET Framework, consultez Garbage Collection.
Notes
L'allocation et la désallocation de mémoire sur le tas managé sont très optimisées dans le common language runtime.Dans la plupart des cas, il n'y a aucune différence significative de performances entre l'allocation d'une instance de classe sur le tas et l'allocation d'une instance de struct sur la pile.
Identité de l'objet VS. l'égalité des valeurs
Lorsque vous comparez deux objets pour l'égalité, vous devez distinguer en premier si vous souhaitez savoir 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 projetez de comparer des valeurs, vous devez savoir si les objets sont des instances de types valeur (structs) ou types référence (classes, délégués, tableaux).
Pour déterminer si deux instances de classe font référence au même emplacement en mémoire (ce qui signifie qu'ils ont la même identité), utilisez la méthode Equals statique. (Object est la classe de base implicite pour tous les types valeur et types référence, y compris les structs et les classes définis par l'utilisateur.)
Pour déterminer si les champs d'instance dans deux instances de struct ont les mêmes valeurs, utilisez la méthode ValueType.Equals. Étant donné que tous les structs héritent implicitement de ValueType, vous appelez directement la méthode sur votre objet comme indiqué dans l'exemple suivant :
// Person is defined in the previous example.
//public struct Person
//{
// public string Name;
// public int Age;
// public Person(string name, int age)
// {
// Name = name;
// Age = age;
// }
//}
Person p1 = new Person("Wallace", 75);
Person p2;
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 ValueType de Equals utilise la réflexion parce qu'elle doit être en mesure de déterminer la nature des champs dans tout struct. Lorsque vous créez vos propres structs, remplacez la méthode Equals pour fournir un algorithme d'égalité efficace et spécifique à votre type.
- 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 == (page éventuellement en anglais). Toutefois, ne les utilisez que si la classe les a remplacé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 ou l'interface IEqualityComparer. Les deux interfaces fournissent des méthodes qui peuvent être utilisées pour tester l'égalité des valeurs. Lorsque vous concevez vos propres classes qui remplacent Equals, veillez à suivre les instructions indiquées dans Comment : définir une égalité de valeurs pour un type (Guide de programmation C#) et Object.Equals(Object).
Rubriques connexes
Pour plus d'informations :
Voir aussi
Référence
Héritage (Guide de programmation C#)