Comment connaître la différence entre le passage d’un struct et le passage d’une référence de classe à une méthode (Guide de programmation C#)How to know the difference between passing a struct and passing a class reference to a method (C# Programming Guide)

L’exemple suivant montre comment le passage d’un struct à une méthode diffère du passage d’une instance de classe à une méthode.The following example demonstrates how passing a struct to a method differs from passing a class instance to a method. Dans l’exemple, les deux arguments (struct et instance de classe) sont passés par valeur, tandis que les deux méthodes changent la valeur d’un champ de l’argument.In the example, both of the arguments (struct and class instance) are passed by value, and both methods change the value of one field of the argument. Toutefois, les résultats des deux méthodes ne sont pas identiques, car ce qui est passé quand vous passez un struct diffère de ce qui est passé quand vous passez une instance d’une classe.However, the results of the two methods are not the same because what is passed when you pass a struct differs from what is passed when you pass an instance of a class.

Étant donné qu’un struct est un type valeur, quand vous passez un struct par valeur à une méthode, la méthode reçoit et traite une copie de l’argument struct.Because a struct is a value type, when you pass a struct by value to a method, the method receives and operates on a copy of the struct argument. La méthode n’a pas accès au struct d’origine dans la méthode d’appel, et ne peut donc pas le modifier de quelque manière que ce soit.The method has no access to the original struct in the calling method and therefore can't change it in any way. La méthode peut modifier uniquement la copie.The method can change only the copy.

Une instance de classe est un type référence, pas un type valeur.A class instance is a reference type, not a value type. Quand un type référence est passé par valeur à une méthode, celle-ci reçoit une copie de la référence à l’instance de classe.When a reference type is passed by value to a method, the method receives a copy of the reference to the class instance. Autrement dit, la méthode appelée reçoit une copie de l’adresse de l’instance, et la méthode appelante conserve l’adresse d’origine de l’instance.That is, the called method receives a copy of the address of the instance, and the calling method retains the original address of the instance. L’instance de classe dans la méthode d’appel a une adresse, le paramètre dans la méthode appelée a une copie de l’adresse, et les deux adresses font référence au même objet.The class instance in the calling method has an address, the parameter in the called method has a copy of the address, and both addresses refer to the same object. Étant donné que le paramètre contient uniquement une copie de l’adresse, la méthode appelée ne peut pas modifier l’adresse de l’instance de la classe dans la méthode.Because the parameter contains only a copy of the address, the called method cannot change the address of the class instance in the calling method. Toutefois, la méthode appelée peut utiliser la copie de l’adresse pour accéder aux membres de la classe qui ont à la fois l’adresse d’origine et la copie de la référence d’adresse.However, the called method can use the copy of the address to access the class members that both the original address and the copy of the address reference. Si la méthode appelée modifie un membre de classe, l’instance de classe d’origine dans la méthode d’appel change également.If the called method changes a class member, the original class instance in the calling method also changes.

La sortie de l’exemple suivant illustre la différence.The output of the following example illustrates the difference. La valeur du champ willIChange de l’instance de classe est changée par l’appel à la méthode ClassTaker, car la méthode utilise l’adresse mentionnée dans le paramètre pour rechercher le champ spécifié de l’instance de classe.The value of the willIChange field of the class instance is changed by the call to method ClassTaker because the method uses the address in the parameter to find the specified field of the class instance. Le champ willIChange du struct de la méthode d’appel n’est pas changé par l’appel à la méthode StructTaker, car la valeur de l’argument est une copie du struct lui-même, et non pas une copie de son adresse.The willIChange field of the struct in the calling method is not changed by the call to method StructTaker because the value of the argument is a copy of the struct itself, not a copy of its address. StructTaker change la copie, et cette dernière est perdue quand l’appel à StructTaker est terminé.StructTaker changes the copy, and the copy is lost when the call to StructTaker is completed.

ExempleExample

using System;

class TheClass
{
    public string willIChange;
}

struct TheStruct
{
    public string willIChange;
}

class TestClassAndStruct
{
    static void ClassTaker(TheClass c)
    {
        c.willIChange = "Changed";
    }

    static void StructTaker(TheStruct s)
    {
        s.willIChange = "Changed";
    }

    static void Main()
    {
        TheClass testClass = new TheClass();
        TheStruct testStruct = new TheStruct();

        testClass.willIChange = "Not Changed";
        testStruct.willIChange = "Not Changed";

        ClassTaker(testClass);
        StructTaker(testStruct);

        Console.WriteLine("Class field = {0}", testClass.willIChange);
        Console.WriteLine("Struct field = {0}", testStruct.willIChange);

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Class field = Changed
    Struct field = Not Changed
*/

Voir aussiSee also