Double Possible:
Comment puis-je vérifier pour les valeurs null dans une ‘==' opérateur de surcharge sans récursion infinie?Il y a probablement une réponse simple à cette...mais il semble être de se soustraire à moi. Voici un exemple simplifié:
public class Person { public string SocialSecurityNumber; public string FirstName; public string LastName; }
Disons que pour cette application particulière, il est vrai de dire que si les numéros de sécurité sociale de match, et les deux noms de match, alors nous nous référons à la même "personne".
public override bool Equals(object Obj) { Person other = (Person)Obj; return (this.SocialSecurityNumber == other.SocialSecurityNumber && this.FirstName == other.FirstName && this.LastName == other.LastName); }
Pour garder les choses cohérentes, nous avons remplacer le == et != les opérateurs, aussi, pour les développeurs de l'équipe qui n'utilisent pas l'
.Equals
méthode.public static bool operator !=(Person person1, Person person2) { return ! person1.Equals(person2); } public static bool operator ==(Person person1, Person person2) { return person1.Equals(person2); }
Fine et dandy, droit?
Cependant, ce qui se passe quand une Personne objet est -
null
?Vous ne pouvez pas écrire:
if (person == null) { //fail! }
Car l'opérateur == substitution d'exécuter, et le code s'échouer sur la:
person.Equals()
appel de la méthode, puisque vous ne pouvez pas appeler une méthode sur une instance null.
D'autre part, vous ne pouvez pas explicitement vérifier cette condition à l'intérieur de l' == remplacer, car il pourrait causer une récursivité infinie (et un Débordement de Pile [dot com])
public static bool operator ==(Person person1, Person person2) { if (person1 == null) { //any code here never gets executed! We first die a slow painful death. } return person1.Equals(person2); }
Alors, comment voulez-vous remplacer le == et != les opérateurs de la valeur de l'égalité et encore de compte pour les objets nuls?
J'espère que la réponse n'est pas douloureusement simple. :-)
Réponses
Trop de publicités?Je l'ai toujours fait de cette façon (pour les opérateurs == et! =) Et je réutilise ce code pour chaque objet que je crée:
public static bool operator ==(Person lhs, Person rhs)
{
// If left hand side is null...
if (System.Object.ReferenceEquals(lhs, null))
{
// ...and right hand side is null...
if (System.Object.ReferenceEquals(rhs, null))
{
//...both are null and are Equal.
return true;
}
// ...right hand side is not null, therefore not Equal.
return false;
}
// Return true if the fields match:
return lhs.Equals(rhs);
}
"! =" va alors comme ceci:
public static bool operator !=(Person lhs, Person rhs)
{
return !(lhs == rhs);
}
modifier
J'ai modifié le ==
fonction de l' opérateur pour correspondre à la mise en œuvre proposée de Microsoft ici .
Surcharger constamment ces opérateurs est assez difficile. Ma réponse à une question connexe peut servir de modèle.
Fondamentalement, vous devez d'abord faire un test de référence ( object.ReferenceEquals
) pour voir si l'objet est null
. Ensuite, vous appelez Equals
.