Objets (Guide de programmation C#)

Mise à jour : novembre 2007

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.

Remarque :

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 et 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 a 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}", person2.Name, person2.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 a 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 a new struct object. Note that a 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 a 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.

Remarque :

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 et é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. (System.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 System.ValueType, vous appelez directement la méthode sur votre objet comme indiqué dans l'exemple suivant :

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 System.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.

Rubriques connexes

Pour plus d'informations :

Voir aussi

Concepts

Guide de programmation C#

Types valeur du système de type commun

Classes du système de type commun

Référence

object (Référence C#)

Héritage (Guide de programmation C#)

class (Référence C#)

struct (Référence C#)

new, opérateur (Référence C#)