web-dev-qa-db-fra.com

Comparer une chaîne et un objet en C #

Voir ce code:

object x = "mehdi emrani";
string y = "mehdi emrani";
Console.WriteLine(y == x);

qui renvoie true.

Mais ce code:

object x = "mehdi emrani";
string y = "mehdi ";
y += "emrani";
Console.WriteLine(y == x);

renvoie false.

Ainsi, lorsque je compare String et Object dans le premier code, j'obtiens true.
Mais quand je les compare dans le deuxième code, j'obtiens false.

Les deux chaînes sont identiques, mais pourquoi lorsque j'ajoute à la chaîne, mon résultat renvoie false?

63
Mehdi Emrani

Dans chaque cas, le deuxième opérande de == Est x, qui est de type object. Cela signifie que vous utilisez l'opérateur d'égalité de référence normal.

Maintenant, dans votre premier cas, vous utilisez deux chaînes constantes avec le même contenu. Le compilateur C # utilisera un seul objet pour ces deux références. Dans le second cas, x et y font référence à des objets chaîne distincts avec le même contenu. Les deux références seront différentes, donc == Renverra false.

Vous pouvez corriger la comparaison en:

  • Utilisez Equals à la place - c'est remplacé par string (par opposition à l'opérateur == Qui est seulement surchargé:

    Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
    

    L'utilisation de la méthode statique Equals(object, object) peut être utile si l'un des arguments peut être nul; cela signifie que vous n'avez pas à vous soucier d'un NullReferenceException.

  • Créez les deux variables de type string, auquel cas la surcharge == Dans string sera choisie au moment de la compilation, et cette surcharge compare le contenu des chaînes, pas seulement les references

Il convient de noter que ce n'est pas seulement une question de littéraux de chaîne lui-même remarqués par le compilateur C # - il s'agit d'expressions constantes au moment de la compilation. Ainsi, par exemple:

object x = "mehdi emrani";
string y = "mehdi " + "emrani";
Console.WriteLine(y == x); // True

Ici y est initialisé en utilisant deux littéraux de chaîne qui ne sont pas identiques à celui utilisé pour initialiser x, mais la concaténation de chaîne est effectuée par le compilateur, qui se rend compte que c'est la même chaîne que celle déjà utilisée pour x.

90
Jon Skeet

Lorsque vous avez initialisé

object x = "mehdi emrani";  //pointer(x)

Il l'a initialisé en mémoire et attribue une référence à x. Après cela, lorsque vous avez initialisé

string y = "mehdi emrani"; //pointer(x)

ref

le compilateur trouve que cette valeur est déjà en mémoire donc il attribue la même référence à y.

Maintenant == L'opérateur égal qui compare réellement les adresses au lieu de valeur trouve la même adresse pour les deux variables, ce qui donne la vérité:

x==y  //actually compares pointer(x)==pointer(x) which is true

Dans le deuxième cas, lorsque vous avez initialisé x et y, des adresses différentes ont été attribuées.

object x = "mehdi emrani";  //Pointer(x)
string y = "mehdi ";        //not found in memory
y += "emrani";              //Pointer(y)

Maintenant, la comparaison trouve différentes adresses qui résultent fausses:

x == y  //is actually Pointer(x) == Pointer(y) which is false

Donc, pour surmonter cela, vous devez utiliser .Equals () qui, au lieu de référence, compare la valeur et le type d'objet.

Console.WriteLine(y.Equals(x));   //compares "mehdi emrani" == "mehdi emrani" results true
30
Zaheer Ahmed

Les références sont très probablement comparées (implémentation standard de Equals pour l'objet). Dans le premier exemple, C # optimise les chaînes constantes, et donc y et x pointent réellement vers le même objet, d'où leur référence est égale. Dans l'autre cas, y est créé dynamiquement et la référence est donc différente.

7
Grzenio

En arrière-plan, une nouvelle chaîne est créée chaque fois que vous modifiez une chaîne existante, car les chaînes sont immuables, ce qui signifie qu'elles ne peuvent pas changer.

Voir l'explication suivante: Pourquoi la chaîne .NET est immuable?

6
DaveDev

Dans le premier cas, .NET effectue une optimisation constante des chaînes et alloue une seule instance de chaîne. Les deux x et y pointent vers le même objet (les deux références sont égales).

Mais dans le second cas, x et y pointent vers différentes instances de String. L'ajout de "ermani" à y crée un troisième objet chaîne.

L'opérateur "==" renvoie fondamentalement vrai si les opérandes des deux côtés font référence au même objet. Dans le premier cas, x et y se réfèrent au même objet et dans le second cas, x & y se réfèrent à des objets différents.

6

As-tu essayé:

Console.WriteLine(y == x.ToString());
3
i486