web-dev-qa-db-fra.com

Pourquoi ne puis-je pas utiliser String.Contains () si la chaîne par défaut est null?

De MSDN doc :

public bool Contains(
    string value
)

Valeur de retour: true si le paramètre value apparaît dans cette chaîne ou si valeur est la chaîne vide (""); sinon, false .

Exception: ArgumentNullException : valeur est null .

Exemple:

string s = string.Empty; //or string s = "";
Console.WriteLine(s.Contains("Hello World!")); //output: False

Si je le change en:

try
{
   string s = null; //or string s;
   Console.WriteLine(s.Contains("Hello World!"));
}
catch (Exception e)
{
   Console.WriteLine(e.Message);
}

Un message d'erreur s'affichera: Object reference not set to an instance of an object puisque string n'a pas de valeur par défaut (telle que "") dans Tableau des valeurs par défaut (référence C #) ,

Veuillez revenir à l'exemple, le code fonctionnera si je déclare s:

string s = "";

Maintenant, Object s est défini sur une instance d'un objet.

Ma question est donc la suivante: MSDN a-t-il oublié quelque chose du genre: s ne peut pas être null ?

Pour le vérifier, j'ai essayé:

string s = null;
Console.WriteLine(!string.IsNullOrEmpty(s) ? s.Contains("Hello World!") : false);

Ça devrait marcher.

9
Foo

Vous avez changé le valeur avec le instance.

myString.Contains(anotherString)

Ici myString est la instance sur laquelle vous appelez la méthode Contains, alors que anotherString est la valeur passée à la méthode. Si cette valeur est null la méthode jettera une ArgumentNullException.

Lorsque vous modifiez instance en null, cela conduit sûrement à NRE car vous ne pouvez appeler aucun membre sur une référence null. Toutefois, si vous le définissez sur string.empty, Contains renverra false car la chaîne vide ne contient pas rien (en particulier, string.empty ne contient pas "Hello World", cependant "Hello world" contient la chaîne vide).

Donc, ce qui suit retourne false:

Console.WriteLine(string.Empty.Contains("Hello World"));

Alors que cela retourne true:

Console.WriteLine("Hello World".Contains(string.Empty));

Quoi qu'il en soit, ce que vous voulez vérifier, c'est si la chaîne vide IS contenue dans une autre:

var retVal = myString.Contains(string.empty);

Ce qui devrait retourner true.

De plus, myString.Contains(null) conduit à ArgumentNullException

De l'autre côté, null.Contains(aString) mène au NRE.

12
HimBromBeere

le nouveau compilateur vous permet de le faire avec la vérification de condition simplifiée.

string s = null;
Console.WriteLine(s?.Contains("Hello World!"));
2
Mike

Il semble que cette question concerne davantage la différence entre les types valeur (qui ne peuvent pas être nuls) et les types référence (qui peuvent être). En C # et dans d'autres langages OO, il s'agit du traitement de la mémoire.

Les types de valeur répertoriés dans votre article MSDN ont tous une taille connue - par exemple. int sera toujours d'une taille de 32 bits, etc. Sous le capot, ce sont tous structs. Comme ils ont une taille fixe quelle que soit la valeur, C # les stocke dans la call stack . Comme null par définition ne fait référence à rien, il n’a pas de taille. Cela n'a pas de sens pour quelque chose qui existe avec une taille fixe d'exister aussi sans taille.

Si vous lisez un peu plus près la documentation de string sur MSDN, vous verrez que string est une classe pas une structure. En effet, une chaîne peut être de n'importe quelle longueur, elle doit donc être stockée sous forme de pointeur vers des données sur heap . Lorsque vous déclarez une variable de type référence, il crée un pointeur sur la pile vers un emplacement du tas, mais il n'y aura rien à cette adresse jusqu'à ce que vous lui donniez une valeur. Jusque-là, le pointeur de cette variable est pointant et la mémoire ne contient littéralement rien - c'est-à-dire nullet cela n'a aucun sens d'essayer de trouver "Hello World!" dans rien. Une chaîne vide est toujours une chaîne, mais null n'est littéralement rien.

C’est probablement plus détaillé que ce à quoi vous vous attendiez, mais il est bon de connaître les principes sous-jacents d’une langue, même si vous n’en avez pas besoin au jour le jour. Cet article mérite une lecture si vous voulez aller un peu plus en profondeur. L'idée de null peut être un concept étrange pour se faire une idée, mais une fois que vous avez compris, tout cela a du sens, honnête!

0
Mourndark