195 votes

Type de référence de chaîne C# ?

Je sais que la "chaîne" en C# est un type de référence. Cela se trouve sur MSDN. Cependant, ce code ne fonctionne pas comme il devrait alors :

class Test
{
    public static void Main()
    {
        string test = "before passing";
        Console.WriteLine(test);
        TestI(test);
        Console.WriteLine(test);
    }

    public static void TestI(string test)
    {
        test = "after passing";
    }
}

La sortie devrait être "before passing" "after passing" puisque je passe la chaîne en tant que paramètre et qu'il s'agit d'un type de référence, la deuxième instruction de sortie devrait reconnaître que le texte a changé dans la méthode TestI. Cependant, j'obtiens "before passing" "before passing", ce qui donne l'impression que le texte est passé par valeur et non par référence. Je comprends que les chaînes de caractères sont immuables, mais je ne vois pas comment cela pourrait expliquer ce qui se passe ici. Qu'est-ce qui m'échappe ? Merci.

5voto

BornToCode Points 887

Les réponses ci-dessus sont utiles, je voudrais juste ajouter un exemple qui, je pense, démontre clairement ce qui se passe lorsque nous passons un paramètre sans le mot clé ref, même lorsque ce paramètre est un type de référence :

MyClass c = new MyClass(); c.MyProperty = "foo";

CNull(c); // only a copy of the reference is sent 
Console.WriteLine(c.MyProperty); // still foo, we only made the copy null
CPropertyChange(c); 
Console.WriteLine(c.MyProperty); // bar

private void CNull(MyClass c2)
        {          
            c2 = null;
        }
private void CPropertyChange(MyClass c2) 
        {
            c2.MyProperty = "bar"; // c2 is a copy, but it refers to the same object that c does (on heap) and modified property would appear on c.MyProperty as well.
        }

3voto

Dimi_Pel Points 127

Très bonne explication dans MSDN également.

0voto

Marius Kjeldahl Points 4325

Essayez :

public static void TestI(ref string test)
    {
        test = "after passing";
    }

0voto

Sahuagin Points 3209

Je crois que votre code est analogue à celui qui suit, et vous n'auriez pas dû vous attendre à ce que la valeur ait changé pour la même raison qu'elle ne le ferait pas ici :

 public static void Main()
 {
     StringWrapper testVariable = new StringWrapper("before passing");
     Console.WriteLine(testVariable);
     TestI(testVariable);
     Console.WriteLine(testVariable);
 }

 public static void TestI(StringWrapper testParameter)
 {
     testParameter = new StringWrapper("after passing");

     // this will change the object that testParameter is pointing/referring
     // to but it doesn't change testVariable unless you use a reference
     // parameter as indicated in other answers
 }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X