10 votes

Est-ce que null == null?

J'ai un objet de type Foo.
Foo a un Id (int)

a) Le code ci-dessous est-il "bon"?
b) Que devrais-je renvoyer si les deux sont nuls?

// surcharge de l'opérateur==
public static bool operator ==(Foo x, Foo y)
{
    if (ReferenceEquals(x, y))
    {
        return true;
    }

    if (x == null && y == null)
    {
        return // ??? 
    }

    if (x == null || y == null)
    {
        return false; 
    }

    return x.Id == y.Id; // Les Id sont les mêmes
}

public static bool Equals(Foo x, Foo y)
{
   return x == y;
}

MODIFICATION:
c) Est-ce que la méthode Equals doit appeler l'opérateur \==, ou vice-versa?

Dernière question
d) Est-il possible que ReferenceEquals(x, y) == true ET x.Id != y.Id?

15voto

Rowland Shaw Points 22860

C'est en fait un code inaccessible, car ReferenceEquals() est documenté pour renvoyer true si les deux opérandes sont nuls.

EDIT: Pour répondre spécifiquement à votre point (d) : lorsque ReferenceEquals() renvoie true, alors les deux références doivent être les mêmes ; elles pointent donc vers le même objet. Donc, sauf si vous faites quelque chose d'imprévisible dans l'accesseur de propriété, les valeurs pour l'Id seront lues à partir du même objet, et seraient attendues d'être les mêmes. (La morale de l'histoire ici est que les propriétés doivent se comporter de manière répétable sans autres effets secondaires comme peut-être allouer un Id si aucun n'est déjà défini)

Il est parfaitement possible que vous puissiez avoir deux objets avec le même Id, mais des références différentes. Par exemple :

Foo a = new Foo();
Foo b = new Foo();

ReferenceEquals() renverrait false lors de la comparaison de a et b (car ce sont des instances différentes), mais à moins que ce constructeur n'ait fait quelque chose comme allouer un Id, je m'attendrais à ce qu'ils partagent cet Id et que votre vérification d'égalité réussisse.

11voto

Aliostad Points 47792

Oui

null n'est rien d'autre qu'un pointeur interne avec une valeur zéro. Donc, il compare deux références ayant une valeur zéro.

En fait, object.ReferenceEquals(null, null) est toujours vrai à cause de ce fait et donc vous n'avez pas besoin de la deuxième vérification.

if (ReferenceEquals(x, y))
{
    return true;
}

if (x == null && y == null) // CETTE VÉRIFICATION EST REDONDANTE!!!
{
    return true;
}

Sur le dernier point, == et Equals sont gérés de la même manière sauf pour les types de valeurs boxés:

        object s1 = 2;
        object s2 =  1+1;

        Console.WriteLine(s1 == s2);
        Console.WriteLine(s1.Equals(s2));

Cela produit false et true.

Point d: NON c'est le même objet, le même espace mémoire - s'ils pointent vers un champ sur l'objet.

4voto

Armen Tsirunyan Points 59548

Oui,

null == null

Je réorganiserais votre code de cette manière

if(x!=null && y!=null)
   return x.id == y.id;
return x == null && y == null;

3voto

Ondrej Tucny Points 13127

ReferenceEquals gère déjà le cas où les deux arguments sont nuls - MSDN indique "true if objA is the same instance as objB or if both are null; otherwise, false." concernant sa valeur de retour.

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