42 votes

Pourquoi le résultat de l'ajout de deux chaînes nulles n'est-il pas nul?

J'ai été bidouiller en C# quand j'ai rencontré cet étrange comportement .Net de programmation.

J'ai écrit ce code:

  static void Main(string[] args)
    {
        string xyz = null;
        xyz += xyz;
        TestNullFunc(xyz);
        Console.WriteLine(xyz);

        Console.Read();

    }

    static void TestNullFunc(string abc)
    {
        if (abc == null)
        {
            Console.WriteLine("meow THERE ! ");
        }
        else
        {
            Console.WriteLine("No Meow ");
        }
    }

J'ai eu la sortie en No meow, ce qui signifie que la chaîne n'est pas null. Comment est-ce possible? Pourquoi ne l'ajout de deux null chaînes, suite à un non-null chaîne de caractères?

Sur le débogage lorsque je vérifie la valeur de xyz après l'ajout de lui-même, sa valeur est "" (pas de personnages).

67voto

dcastro Points 17978

À partir de MSDN:

Dans la concaténation de chaîne des opérations, le compilateur C# traite une chaîne null le même comme une chaîne vide,

Même si xyz est null, l'appel de l'opérateur + = (qui est ensuite converti en un appel à l' opérateur+ (*)) sur ce, il ne jette pas un NullReferenceException parce que c'est un statique de la méthode. En pseudo-code:

xyz = String.+(null, null);

La mise en œuvre sera alors interpréter cela comme si c'était

xyz = String.+("", "");

(*) La Section §7.17.2 de la spécification C#:

Une opération de la forme x op= y est traitée par l'application d'opérateur binaire résolution de surcharge (§7.3.4) comme si l'opération a été écrit x op y.

24voto

Alberto Points 5865

Lorsque vous utilisez l' += opérateur, vous êtes en fait de l'appel de la chaîne.Concat méthode, qui, comme indiqué dans la documentation:

La méthode concatène str0 et str1; il n'ajoute pas les délimiteurs. Une chaîne Vide est utilisé à la place de tout argument null.

En fait ce code:

string xyz = null;
xyz += xyz;

seront compilées dans:

IL_0000:  ldnull      
IL_0001:  stloc.0     // xyz
IL_0002:  ldloc.0     // xyz
IL_0003:  ldloc.0     // xyz
IL_0004:  call        System.String.Concat
IL_0009:  stloc.0     // xyz

6voto

Jon Hanna Points 40291

Comme l'a dit, la raison en est que la concaténation de la valeur null est la même que la concaténation d'une chaîne vide.

Il vaut la peine de se demander pourquoi ce comportement est utile.

Normalement, il y a deux choses sensibles que nous pouvons faire avec un opérateur binaire lorsque l'un des opérandes est nulle:

  1. Le résultat est null.
  2. L'opération est un no-op, et nous êtes de gauche avec l'autre opérande.

Il est logique, par exemple, que ((int?)null) + 3 résultats en null, et en général ce sera le plus utile résultat, ou un nous avons consciemment en garde contre (qui est, nous allons ajouter du code pour attraper la valeur null explicitement).

Mais il y a deux raisons pour ne pas le faire avec la concaténation de chaîne.

La première est de considérer que, puisque la concaténation ne signifie pas un calcul arithmétique, mais en restant deux choses ensemble, alors ce qui est le plus raisonnable résultat de coller null sur le début ou la fin de quelque chose? Il est facile de faire le cas que cela devrait ne rien faire, plutôt que de retourner la valeur null.

La deuxième est que, dans la pratique, il y aura moins de cas où nous voulons a + b + c + d , avec des cordes à retourner la valeur null si l'un de ceux qui sont nuls, que dans le cas où nous ne serions pas.

Et à partir de cela, il est logique de traiter la valeur null comme une chaîne vide dans les concaténations. À partir de cette base, qui (string)null + (string)null résultats en "" est parce que nous n'avons pas un cas particulier pour la concaténation de trop les valeurs null.

Ce cas particulier pourrait être ajouté, mais ensuite, la propriété x + "" == x + null ne serait plus tenir, ce qui pourrait conduire à une étrange cas.

2voto

Gokul Jai Points 491

C’est parce que l’opérateur += ajoute les chaînes nulles à vides.

Le compilateur ajoute donc une chaîne vide à l'objet string existant.

Donc, il est vide et non nul.

2voto

Amit Tiwari Points 131

essaye ça...

 static void TestNullFunc(string abc)
{
    if (string.IsNullOrEmpty( abc))
    {
        Console.WriteLine("meow THERE ! ");
    }
    else
    {
        Console.WriteLine("No Meow ");
    }
}
 

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