Considérese la clase siguiente:¿Cómo verificar nulo en el operador == método?
public class Code : IEquatable<Code>
{
public string Value { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as Code);
}
public override bool Equals(Code code)
{
if (code == null) return false;
return this.Value == code.Value;
}
public static bool operator ==(Code a, Code b)
{
if (a == null) return b == null;
return a.Equals(b);
}
public static bool operator !=(Code a, Code b)
{
if (a == null) return b!= null;
return !a.Equals(b);
}
// rest of the class here
}
Ahora trate de usar el método ==
:
Code a = new Code();
Code b = new Code();
Console.WriteLine("The same? {0}", a==b);
El resultado es una StackOverflowException
porque el método ==
llama a sí mismo cuando se comprueba nula.
Pero si tomo el cheque nulo:
public static bool operator ==(Code a, Code b)
{
return a.Equals(b);
}
me siento un NullReferenceException
!
¿Cuál es la forma correcta de definir estos métodos?
Hay una alternativa a esta solución que actualmente tiene más votos ascendentes, así que permítanme observar que '(objeto) a == null' da como resultado un código más rápido, en la medida en que una implementación' ReferenceEquals' op == tomó más del doble siempre y cuando el equivalente use '(object) a == null'. Si usa el mismo código también para 'Equals', esto puede tener un efecto de arrastre en cada' Distinct() ',' Dictionary <> ',' HashSet <> ',' ToLookup' etc. que use con este tipo como la llave. –
Una microbenchmark Linqpad para aquellos interesados en replicar el problema de rendimiento con 'ReferenceEquals': https://github.com/EamonNerbonne/ValueUtils/blob/master/NullCheckBenchmark.linq. Tenga en cuenta que, al parecer, a veces el CLR lo alinea, por lo que si tiene suerte no importará. –