2010-12-29 14 views
19

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?

Respuesta

26

También puede utilizar (object)a == null

+0

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. –

+0

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á. –

Cuestiones relacionadas