Pourquoi ces deux comparaisons ont-elles des résultats différents?

Pourquoi ce code retourne true:

new Byte() == new Byte() // returns true 

mais ce code retourne false:

 new Byte[0] == new Byte[0] // returns false 

Parce que le new Byte() crée un type de valeur, qui est comparé par valeur (par défaut, il retournera un byte avec la valeur 0 ). Et new Byte[0] crée un tableau, qui est un type de référence et comparé par référence (et ces deux instances de tableau auront des références différentes).

Voir l’article Types de valeur et types de référence pour plus de détails.

Les octets sont des types de valeur dans .NET, ce qui signifie que l’opérateur == renvoie true si et seulement si les deux octets ont la même valeur. Ceci est également connu sous le nom d’ égalité de valeur .

Mais les tableaux sont des types de référence dans .NET, ce qui signifie que l’opérateur == renvoie true si et seulement s’ils font référence à la même instance de tableau en mémoire. Ceci est également connu sous le nom d’ égalité ou d’ identité de référence .

Notez que l’opérateur == peut être surchargé pour les types référence et valeur. System.Ssortingng , par exemple, est un type de référence, mais l’opérateur == pour les chaînes compare chaque caractère du tableau en séquence. Voir les directives pour la surcharge d’Equals () et de l’opérateur == (Guide de programmation C #) .

Si vous voulez tester si les tableaux contiennent exactement les mêmes valeurs (dans l’ordre), vous devriez envisager d’utiliser Enumerable.SequenceEqual au lieu de == .

La référence de comparaison compare en fait l’adresse du pointeur, qui est différente, c’est-à-dire que la raison renvoyée est false et que l’adresse de la valeur importe peu qu’elle compare la valeur.

Le compilateur essaie de stocker le type de valeur dans les registres, mais en raison du nombre limité de registres, un stockage supplémentaire se produit dans Stack avec les valeurs [Reference] alors que le type de référence est en stack

Comparaison ici comparer la valeur présente dans la stack qui est dans le premier cas pour les deux mêmes alors que dans le second cas, ce sont les adresses de tas qui sont différentes.

référence

Il y a une surcharge de l’opérateur == dans lequel les deux opérandes sont de type byte et il est implémenté pour comparer la valeur de chaque octet; dans ce cas, vous avez deux octets de zéro, et ils sont égaux.

L’opérateur == n’est pas surchargé pour les tableaux, de sorte que la surcharge comportant deux opérandes d’ object est utilisée (puisque les tableaux sont de type object ) dans le second cas, et que son implémentation compare les références aux deux objects. La référence aux deux tableaux est différente.

Il convient de noter que cela n’a rien à voir avec le fait que l’ byte est un type de valeur et que les tableaux sont des types de référence. L’opérateur == pour l’ byte n’a de sémantique que parce qu’il y a une surcharge spécifique de l’opérateur avec cette implémentation. Si cette surcharge n’existait pas, il n’y aurait pas de surcharge pour laquelle deux octets seraient des opérandes valides et le code ne serait pas compilé du tout . Vous pouvez le voir assez facilement en créant une struct personnalisée et en en comparant deux avec l’opérateur == . Le code ne sera pas compilé, sauf si vous fournissez votre propre implémentation de == pour ces types.