Ne pouvez pas l'opérateur == être appliquée à des types génériques en C#?

Selon la documentation de la == opérateur dans MSDN,

Prédéfinis pour différents types de valeurs, l'
opérateur d'égalité (==) retourne vrai si
les valeurs de ses opérandes sont égaux,
sinon false. Pour les types référence
autres que string, == retourne true si
ses deux opérandes reportez-vous à la même
objet. Pour le type de chaîne, ==
compare les valeurs des chaînes de caractères.
Valeur définie par l'utilisateur les types de surcharge
l'opérateur = = (voir opérateur). Donc peut
défini par l'utilisateur des types de référence, bien que
par défaut == se comporte comme décrit
ci-dessus pour les deux prédéfinis et
défini par l'utilisateur des types référence.

Alors pourquoi ce bout de code ne parviennent pas à compiler?

bool Compare<T>(T x, T y) { return x == y; }

Je reçois le message d'erreur Opérateur '==' ne peut pas être appliquée à des opérandes de type 'T' et 'T'. Je me demande pourquoi, depuis aussi loin que je comprends le == opérateur est prédéfini pour tous les types?

Edit: Merci, tout le monde. Je n'avais pas remarqué au premier abord que la déclaration a propos des types de référence seulement. Je pensais aussi que bit-par-bit de comparaison est fourni pour tous les types de valeur, je sais maintenant est pas correcte.

Mais, dans le cas où je suis en utilisant un type de référence, le == opérateur prédéfini référence de comparaison, ou d'utiliser la version surchargée de l'opérateur si un type défini un?

Edit 2: Par essais et erreurs, nous avons appris que le == opérateur utilisera le prédéfinies de référence de comparaison lors de l'utilisation sans restriction de type générique. En fait, le compilateur utilisera la meilleure méthode, il peut trouver de l'restreinte type d'argument, mais ne cherchez pas plus loin. Par exemple, le code ci-dessous, imprimez toujours true, même lorsque Test.test<B>(new B(), new B()) est appelé:

class A { public static bool operator==(A x, A y) { return true; } }
class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T b) where T : A { Console.WriteLine(a == b); } }
Voir ma réponse, là encore, la réponse à votre question de suivi.
Il pourrait être utile de comprendre que, même sans les génériques, il y a quelques types pour lesquels la == n'est pas autorisé entre les deux opérandes de même type. Cela est vrai pour struct types (à l'exception de "pré-défini") qui ne surchargez pas le operator ==. Comme exemple simple, essayez ceci: var map = typeof(string).GetInterfaceMap(typeof(ICloneable)); Console.WriteLine(map == map); /* compile-time error */
En continuant mon propre ancien commentaire. Par exemple (voir la section autre thread), avec var kvp1 = new KeyValuePair<int, int>(); var kvp2 = kvp1;, alors vous ne pouvez pas vérifier kvp1 == kvp2 parce que KeyValuePair<,> est une struct, il n'est pas un C# pré-défini le type de, et il ne surcharge pas le operator ==. Encore un exemple en est donné par var li = new List<int>(); var e1 = li.GetEnumerator(); var e2 = e1; avec qui vous ne pouvez pas faire e1 == e2 (ici, nous avons le imbriquée struct List<>.Enumerator (appelé "List`1+Enumerator[T]" par le moteur d'exécution) qui ne surcharge pas ==).
RE: "pourquoi ce bout de code ne parviennent pas à compiler?" -- Euh... parce que vous ne pouvez pas retourner un bool à partir d'un void...
Merci pour attraper un 10-year-old bug!

OriginalL'auteur Hosam Aly | 2008-12-24