45 votes

Comment fonctionne l'ajout à une chaîne de caractères nulle en C# ?

J'ai été surpris de voir un exemple de chaîne de caractères initialisée à null et à laquelle on ajoute quelque chose dans un environnement de production. Cela ne me semblait pas correct.

J'étais sûr que cela aurait déclenché une exception pour objet nul, mais cet exemple très réduit fonctionne également :

string sample = null;
sample += "test";
// sample equals "test"

* Notez que le code original que j'ai trouvé définit une propriété de chaîne à null et l'ajoute ailleurs, donc les réponses impliquant le compilateur optimisant le null au moment de la compilation ne sont pas pertinentes.

Quelqu'un peut-il expliquer pourquoi cela fonctionne sans erreur ?

Suivi :

Sur la base de la réponse de Leppie, j'ai utilisé Reflector pour voir ce qui se trouve dans string.Concat. La raison pour laquelle cette conversion a lieu est maintenant très évidente (pas de magie du tout) :

public static string Concat(string str0, string str1)
{
    if (IsNullOrEmpty(str0))
    {
        if (IsNullOrEmpty(str1))
        {
            return Empty;
        }
        return str1;
    }
    if (IsNullOrEmpty(str1))
    {
        return str0;
    }
    int length = str0.Length;
    string dest = FastAllocateString(length + str1.Length);
    FillStringChecked(dest, 0, str0);
    FillStringChecked(dest, length, str1);
    return dest;
}

** Remarque : l'implémentation spécifique que j'ai étudiée (dans la bibliothèque .Net de Microsoft) ne convertit pas les chaînes vides comme le suggèrent les normes C# et la plupart des réponses, mais utilise quelques tests pour raccourcir le processus. Le résultat final est le même que si elle le faisait, mais voilà :)

47voto

leppie Points 67289

le site + pour les chaînes de caractères sont juste un raccourci de l'opérateur string.Concat qui transforme simplement null en chaînes vides avant la concaténation.

Mise à jour :

La version généralisée de string.Concat :

public static string Concat(params string[] values)
{
    int num = 0;
    if (values == null)
    {
        throw new ArgumentNullException("values");
    }
    string[] array = new string[values.Length];
    for (int i = 0; i < values.Length; i++)
    {
        string text = values[i];
        array[i] = ((text == null) ? string.Empty : text);
        num += array[i].Length;
        if (num < 0)
        {
            throw new OutOfMemoryException();
        }
    }
    return string.ConcatArray(array, num);
}

7voto

Rasmus Faber Points 24195

La citation pertinente doit être ECMA-334 §14.7.4 :

Concaténation de chaînes de caractères :

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);  

Le binaire + L'opérateur de concaténation de chaînes de caractères effectue la concaténation de chaînes de caractères lorsqu'un ou deux opérandes sont de type string . Si un opérande de la chaîne de caractères est null une chaîne vide est substituée. Sinon, tout opérande qui n'est pas une chaîne est converti en sa représentation de chaîne en invoquant la fonction virtuelle ToString méthode héritée du type object . Si ToString renvoie à null une chaîne vide est substituée.

3voto

Damith Points 32311

c'est parce que

Dans les opérations de concaténation de chaînes de caractères, le compilateur C# traite une chaîne de caractères nulle de la même manière qu'une chaîne de caractères vide. comme une chaîne vide, mais il ne convertit pas la valeur de la chaîne nulle d'origine. de la chaîne nulle d'origine.

De Comment faire : Concaténer plusieurs chaînes de caractères (Guide de programmation C#)

L'opérateur binaire + effectue une concaténation de chaînes de caractères lorsque l'un ou les deux opérandes sont de type chaîne de caractères. Si un opérande de la concaténation de chaînes de caractères est null, une chaîne vide est substituée. Sinon, tout argument autre qu'une chaîne de caractères est converti en sa représentation chaîne de caractères en invoquant la méthode virtuelle méthode virtuelle ToString héritée du type object. Si ToString renvoie un résultat nul, une chaîne vide est substituée.

De Opérateur d'addition

1voto

Aliostad Points 47792

Voici le résultat de la compilation de votre code

string sample = null;
sample += "test";

est compilé en ce code IL :

.entrypoint
  // Code size       16 (0x10)
  .maxstack  2
  .locals init ([0] string sample)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldstr      "test"
  IL_0009:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_000e:  stloc.0
  IL_000f:  ret

Et String.Concat s'occupe de la chaîne NULL.

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