J'ai pensé qu'il était temps de mettre à jour l'implémentation des réponses précédentes vers .Net4.0+, où les génériques ne sont plus nécessaires grâce à la contravariance sur le modèle d'implémentation. IEqualityComparer<in T>
interface :
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public sealed class ReferenceEqualityComparer
: IEqualityComparer, IEqualityComparer<object>
{
private ReferenceEqualityComparer() { }
public static readonly ReferenceEqualityComparer Default
= new ReferenceEqualityComparer();
public /*new*/ bool Equals(object x, object y)
{
return x == y; // This is reference equality! (See explanation below)
}
public int GetHashCode(object obj)
{
return RuntimeHelpers.GetHashCode(obj);
}
}
Il suffit maintenant d'une seule instance pour toutes les vérifications de l'égalité des références, au lieu d'une pour chaque type. T
comme c'était le cas auparavant.
Vous n'avez plus besoin de spécifier T
à chaque fois que vous voulez l'utiliser et éviter également de polluer avec des types d'exécution génériques inutiles.
Quant à savoir pourquoi x == y
est une égalité de référence, c'est parce que le ==
est une méthode statique, ce qui signifie qu'elle est résolue au moment de la compilation, et qu'au moment de la compilation, l'opérateur x
y y
Les arguments sont de type object
.
En fait, c'est ce que le Object.ReferenceEquals(object, object)
méthode source code ressemble :
public static bool ReferenceEquals(object objA, object objB) {
return objA == objB;
}
Pour clarifier pour ceux qui ne sont pas familiers avec les concepts de Covariance et contravariance ...
class MyClass
{
ISet<MyClass> setOfMyClass = new HashSet<MyClass>(ReferenceEqualityComparer.Default);
}
...le code ci-dessus compile ; Remarquez qu'il fait no dites HashSet<object>
.
5 votes
.Net 5.0 introduira ReferenceEqualityComparer comme mentionné dans Top 10 des nouvelles API de .NET 5.0 - point 2) qui fait également référence à cette question.