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
?
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
.
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)
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
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.
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?
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.
As-tu essayé:
Console.WriteLine(y == x.ToString());