Ce qui suit provoquera une récursion infinie sur la méthode de surcharge de l'opérateur ==
Foo foo1 = null;
Foo foo2 = new Foo();
Assert.IsFalse(foo1 == foo2);
public static bool operator ==(Foo foo1, Foo foo2) {
if (foo1 == null) return foo2 == null;
return foo1.Equals(foo2);
}
Comment vérifier les valeurs nulles?
c#
.net
operator-overloading
Andrew Jones
la source
la source
Assert.IsFalse(foo2 == foo1);
foo1.Equals(foo2)
signifie si, par exemple, jefoo1 == foo2
ne veux que sifoo1.x == foo2.x && foo1.y == foo2.y
? N'est-ce pas une réponse ignorant le cas oùfoo1 != null
maisfoo2 == null
?if (foo1 is null) return foo2 is null;
Cast en objet dans la méthode de surcharge:
la source
(object)foo1 == null
oufoo1 == (object)null
iront à la surcharge intégrée==(object, object)
et non à la surcharge définie par l'utilisateur==(Foo, Foo)
. C'est comme la résolution de surcharge sur les méthodes.Utilisez
ReferenceEquals
. Depuis les forums MSDN :la source
Essayer
Object.ReferenceEquals(foo1, null)
Quoi qu'il en soit, je ne recommanderais pas de surcharger l'
==
opérateur; il doit être utilisé pour comparer des références etEquals
pour des comparaisons «sémantiques».la source
Si je l' ai substituée
bool Equals(object obj)
et je veux l'opérateur==
etFoo.Equals(object obj)
de retourner la même valeur, je mets en œuvre habituellement l'!=
opérateur comme celui - ci:L'opérateur
==
, après avoir effectué toutes les vérifications nulles pour moi, finira par appelerfoo1.Equals(foo2)
que j'ai remplacé pour faire la vérification réelle si les deux sont égaux.la source
Object.Equals(Object, Object)
côte à côte avecObject.ReferenceEquals(Object, Object)
, il est assez clair queObject.Equals(Object, Object)
tout fait comme suggéré dans les autres réponses hors de la boîte. Pourquoi ne pas l'utiliser?==
opérateur si tout ce que vous voulez est le comportement par défaut. Vous ne devez surcharger que lorsque vous avez besoin d'implémenter une logique de comparaison personnalisée, c'est-à-dire quelque chose de plus qu'une vérification d'égalité des références.==
est souhaitable (la question l'implique), je soutiens simplement cette réponse en suggérant que d'Object.Equals(Object, Object)
autres astuces comme l'utilisationReferenceEquals
ou les cast explicites sont inutiles (donc "pourquoi ne pas l'utiliser?", "ça" êtreEquals(Object, Object)
). Même si sans rapport, votre point est également correct, et j'irais plus loin: seule surcharge==
pour les objets que nous pouvons classer comme "objets de valeur".Object.Equals(Object, Object)
appelle à son tour Object.Equals (Object) qui est une méthode virtuelle que Foo remplace probablement. Le fait que vous ayez introduit un appel virtuel dans votre vérification d'égalité peut affecter la capacité du compilateur à optimiser (par exemple en ligne) ces appels. C'est probablement négligeable dans la plupart des cas, mais dans certains cas, un petit coût dans un opérateur d'égalité peut signifier un coût énorme pour les boucles ou les structures de données triées.Si vous utilisez C # 7 ou une version ultérieure, vous pouvez utiliser la correspondance de modèle à constante nulle:
Cela vous donne un code légèrement plus net que celui de l'objet appelant.ReferenceEquals (foo1, null)
la source
public static bool operator==( Foo foo1, Foo foo2 ) => foo1?.Equals( foo2 ) ?? foo2 is null;
Il existe en fait un moyen plus simple de vérifier
null
dans ce cas:C'est tout!
Cette fonctionnalité a été introduite en C # 7
la source
Mon approche est de faire
sur lequel je me fie à son
object
propre opérateur d'égalité qui ne peut pas aller mal. Ou une méthode d'extension personnalisée (et une surcharge):ou pour traiter plus de cas, peut être:
La contrainte empêche
IsNull
les types valeur. Maintenant c'est aussi doux que d'appelerce qui signifie que j'ai un style cohérent / non sujet aux erreurs de vérification des valeurs nulles partout. J'ai aussi trouvé que
(object)item == null
c'est très très très légèrement plus rapide queObject.ReferenceEquals(item, null)
, mais seulement si cela compte (je travaille actuellement sur quelque chose où je dois tout micro-optimiser!).Pour consulter un guide complet sur la mise en œuvre des vérifications d'égalité, consultez Qu'est - ce que la «meilleure pratique» pour comparer deux instances d'un type de référence?
la source
DbNull
, OMI les cas où cela ne générerait pas de problèmes liés à SRP sont assez rares. En soulignant simplement l'odeur du code, cela pourrait très bien être approprié.La
Equals(Object, Object)
méthode statique indique si deux objets,objA
etobjB
, sont égaux. Il vous permet également de tester des objets dont la valeur estnull
pour l'égalité. Il compareobjA
etobjB
pour l'égalité comme suit:true
. Ce test équivaut à appeler laReferenceEquals
méthode. De plus, si les deuxobjA
etobjB
sontnull
, la méthode retournetrue
.objA
ou l' autreobjB
estnull
. Si tel est le cas, il revientfalse
. Si les deux objets ne représentent pas la même référence d'objet et que ni l'un ni l'autre ne l'estnull
, il appelleobjA.Equals(objB)
et renvoie le résultat. Cela signifie que s'ilobjA
remplace laObject.Equals(Object)
méthode, ce remplacement est appelé..
la source
répondre plus à opérateur de remplacement comment comparer à null qui redirige ici comme un doublon.
Dans les cas où cela est fait pour prendre en charge les objets de valeur, je trouve la nouvelle notation pratique et j'aime m'assurer qu'il n'y a qu'un seul endroit où la comparaison est faite. Exploiter également Object.Equals (A, B) simplifie les vérifications nulles.
Cela surchargera ==,! =, Equals et GetHashCode
Pour les objets plus compliqués, ajoutez des comparaisons supplémentaires dans Equals et un GetHashCode plus riche.
la source
Pour une syntaxe moderne et condensée:
la source
Regarde ça
Reference Guidelines for Overloading Equals () et Operator ==
la source
Vous pouvez essayer d'utiliser une propriété d'objet et intercepter l'exception NullReferenceException résultante. Si la propriété que vous essayez est héritée ou remplacée par Object, cela fonctionne pour n'importe quelle classe.
la source