43 votes

5 façons de vérifier l’égalité en .net .. pourquoi? et lequel utiliser?

Pendant l'apprentissage .net (c#), j'ai trouvé 5 façons pour la vérification de l'égalité entre les objets.

  1. Le ReferenceEquals() la méthode.
  2. Le virtuel méthode Equals (). (Le système.Objet)
  3. La statique de la méthode Equals ().
  4. La méthode Equals de IEquatable interface.
  5. L'opérateur de comparaison == .

Ma question est :

  1. Pourquoi il y a tellement de méthode Equals() avec l'opérateur de comparaison?
  2. Qui virtuel Equals() ou IEquatable de Equals() sholud être utilisé .. (dire si nous utilisons nos propres classes de collection)

31voto

mverardo Points 370

1 - Référence est égal vérifie si deux variables de type(cours, pas les structures) sont soumises à la même adresse mémoire.

2 - Le virtuel méthode Equals() vérifie si deux objets sont équivalents. Disons que vous avez de cette classe:

class TestClass{
    public int Property1{get;set}
    public int Property2{get;set}

    public override bool Equals(object obj)
    {
        if (obj.GetType() != typeof(TestClass))
            return false;

        var convertedObj = (TestClass)obj;

        return (convertedObj.Property1 == this.Property1 && convertedObj.Property2 == this.Property2);
    }
}

et vous instanciez 2 les objets de cette classe:

var o1 = new TestClass{property1 = 1, property2 = 2}
var o2 = new TestClass{property1 = 1, property2 = 2}

bien que les deux objets ne sont pas sur la même instance de TestClass, l'appel à o1.Equals(o2) retournera true.

3 - La statique de la méthode Equals est utilisé pour traiter les problèmes quand il y a une valeur null dans la case. Imaginez ceci, par exemple:

TestClass o1 = null;
var o2 = new TestClass{property1 = 1, property2 = 2}

Si vous essayez ceci:

o1.Equals(o2);

vous allez obtenir une NullReferenceException, parce que o1 points pour rien. Pour régler ce problème, vous n'avez ceci:

Objet.Equals(o1,o2);

Cette méthode est préparé à gérer des références nulles.

4 - La IEquatable interface est fourni par .Net si vous n'avez pas besoin de faire des moulages à l'intérieur de votre méthode Equals. Si le compilateur trouve que vous avez mis en place l'interface dans une classe pour le type que vous essayez de vérifier l'égalité, il va donner la méthode la priorité sur l'Objet.Equals(Object) remplacer. Par exemple:

class TestClass : IEquatable<TestClass>
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }

    public override bool Equals(object obj)
    {
        if (obj.GetType() != typeof(TestClass))
            return false;

        var convertedObj = (TestClass)obj;

        return (convertedObj.Property1 == this.Property1 && convertedObj.Property2 == this.Property2);
    }

    #region IEquatable<TestClass> Members

    public bool Equals(TestClass other)
    {
        return (other.Property1 == this.Property1 && other.Property2 == this.Property2);
    }

    #endregion
}

maintenant, si nous faisons cela:

var o1 = new TestClass{property1 = 1, property2 = 2}
var o2 = new TestClass{property1 = 1, property2 = 2}
o1.Equals(o2);

La méthode appelée est Égal à(TestClass), avant Equals(Object).

5 - L'opérateur == signifie généralement la même que ReferenceEquals, il vérifie si les deux variables pointent vers la même adresse mémoire. Gotcha est que cet opérateur peut être surdéfini effectuer d'autres types de contrôles. Dans les chaînes, par exemple, il vérifie si les deux instances différentes sont équivalentes.

C'est un lien utile pour comprendre les égalités dans .Net mieux:

28voto

Matt Mitchell Points 17005

Le ReferenceEquals() la méthode.

Ce est utilisé pour tester si deux variables (le symbole de références) pour le même objet. Littéralement, c'est équivalent à ((object)a) == ((object)b). Si vous remplacez l'opérateur de comparaison (==) alors ReferenceEquals maintient un moyen d'accéder au comportement par défaut.

Toutefois, si vous avez affaire à un type de valeur (par exemple, une structure (struct), puis cela renverra toujours false. C'est parce que la comparaison des boîtes de chaque type de valeur à un nouvel objet, c'est donc naturellement que les références ne seront pas égales.


Le virtuel méthode Equals (). (Le système.Objet)

C'est la méthode par défaut pour sémantiquement comparer deux objets (de tout type). Chaque classe remplace ce qu'ils choisissent. Par défaut, il est équivalent à un CLR appel (InternalEquals) que, fondamentalement, compare les références de mémoire.

Remarque, si deux objets retourner true pour Equals() alors GetHashCode() sur chacun d'eux doit être égale. Toutefois, si les codes de hachage pour les deux objets sont de valeur équivalente (c - obj1.GetHashCode() == obj2.GetHashCode()) ce n'est pas signifie qu' Equals() est vrai.

Votre classe doit généralement en œuvre Equals et GetHashCode comme un moyen de distinguer les instances de classe, et doit mettre en œuvre le présent ou l' == opérateur (idéalement deux) si c'est un type de valeur.

Remarque, pour les types de valeur par défaut Equals comportement est celui d' ValueType.Equals() qui, si vous regardez dans le Réflecteur (ou de lire la MSDN description) utilise la réflexion pour comparer les membres des deux de la valeur des instances.


La statique de la méthode Equals ().

C'est l'équivalent d' return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))) où chaque type est converti en Object pour le test. Mes tests montre que la surcharge des opérateurs de comparaison sont ignorés, mais votre Equals méthode sera utilisée si les objets ne sont pas nulles et ne sont pas de la même référence. En tant que tel, a.Equals(b) n'est pas nécessairement égal object.Equals(a, b) (pour les cas où l' ((object)a) == ((object)b) ou a ou b est nul).


La méthode Equals de IEquatable interface.

IEquatable fournit un moyen pour vous de traiter comparaison à des instances de la même classe spéciale. Après avoir dit que votre Equals méthode devrait être de la manipulation du comportement de la même façon:

Si vous mettez en œuvre d'égal à Égal, vous devriez également remplacer la classe de base les implémentations de Objet.Equals(Object) et GetHashCode de sorte que leur comportement est cohérent avec que de la IEquatable.Est égal à méthode

Néanmoins, vous devriez mettre en œuvre IEquatable:

Pour gérer la possibilité que les objets d'une classe seront stockés dans un tableau ou un générique objet de collection, il est une bonne idée pour mettre en œuvre IEquatable de sorte que l'objet peut être facilement identifié et manipulé.


L'opérateur de comparaison ==

L'opérateur de comparaison par défaut renvoie vrai si les deux objets sont de la même référence.

Il n'est pas recommandé de remplacer l'opérateur de comparaison, sauf si vous faites affaire avec un type de la valeur (dans ce cas, il est recommandé, ainsi que l' Equals méthode) ou immuable type de référence qui vous aurait généralement comparer en valeur (par exemple, string). Toujours mettre en oeuvre != à la même heure (en fait, je reçois un requires a matching operator '!=' to also be defined d'erreur si je n'ai pas).


Ressources:

2voto

Stephen Cleary Points 91731

Chaque version de l'égalité est légèrement différente.

ReferenceEquals tests de référence pour l'égalité.

virtual Equals par défaut vérifie la référence à l'égalité pour les types de classe et de la valeur de l'égalité pour les struct types. Elle peut être remplacée pour définir l'égalité différemment, si désiré; et devrait être remplacé pour des types de valeur.

static Equals seulement des appels virtual Equals, mais permet aussi de null arguments.

IEquatable<T>.Equals est un générique/type-safe équivalent pour virtual Equals.

operator== est destiné à être comme la valeur par défaut virtual Equals, signification référence de l'égalité pour les types de classe (à moins que la classe remplace également les autres opérateurs). Il devrait également être annulé pour les types de valeur.

Si vous écrivez votre propre classe de collection, utilisez IEqualityComparer<T>, par défaut EqualityComparer<T>.Default. N'utilisez pas l'un de l'égalité des comparaisons directement.

0voto

Aaronontheweb Points 2303

Pour les primitives, coller avec l'opérateur==.

Dans la plupart des objets fournis dans le .NET framework et tous les objets que vous créez le .Méthode Equals() et l'opérateur == ne vérifier pour voir si les deux objets font référence au même objet sur le tas.

Le but de la IEquatable interface est de remplacer la .Méthode Equals() pour modifier son comportement de vérification pour référentielle de l'égalité de vérifier l'égalité des valeurs. Le Système.Type de chaîne est un exemple de construit .NET un objet qui implémente cette interface.

L' .ReferenceEquals() la méthode fournit un moyen pour les développeurs qui ont remplacé la norme .Méthode Equals() pour toujours être en mesure de vérifier deux objets de référentiel de l'égalité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X