2010-05-23 17 views
12

Estaba mirando el proyecto "Domain Oriented N-Layered .NET 4.0 Sample App" y encontré un código que no entiendo. En este proyecto que a menudo utilizan la siguiente sintaxis para comprobar los argumentos de nulo:¿Por qué arrojar nulo antes de verificar si el objeto es igual a nulo?

public GenericRepository(IQueryableContext context,ITraceManager traceManager) 
{ 
    if (context == (IQueryableContext)null) 
      throw new ArgumentNullException("context", Resources.Messages.exception_ContainerCannotBeNull); 

¿por qué te fundido nula con el tipo de objeto que está mirando para nula?

+4

No creo que haya una razón en absoluto, ya que 'null' es' nulo' - no tiene ningún tipo. Pueden ser conformes con algunos * solo debes verificar objetos del mismo tipo para el argumento de igualdad *, pero me parece un poco ridículo ... –

+2

No sé, quizás ellos piensen que es por legibilidad/auto documentación? – Alan

+0

¿Dónde está esta clase en el modelo de dominio? – R0MANARMY

Respuesta

14

No tiene sentido en el ejemplo dado.

Aunque no es aplicable en este caso, a veces hay una necesidad de echar nula (o al menos no había antes del incumplimiento (T) se añadió en cuenta lo siguiente:.

void DoSomething(string x) { 
    ... 
} 

void DoSomething(object x) { 
    ... 
} 

DoSomething(null);   // compiler can't infer the type 
DoSomething((string)null); // string type is now explicit 
DoSomething(default(string)); // same as previous 

EDITAR

Acabo de pensar en otro caso en el que tendrías que hacer el yeso al probar la igualdad. Si tuvieras un objeto que tuviera un operador == sobrecargado que permitiera la comparación con dos tipos de referencia, la comparación con el nulo sería ambigua. Sin embargo, porque IQueryableContext es más Probablemente una interfaz e interfaces no pueden overlo y el operador ==, todavía no veo ninguna razón válida para hacerlo en el ejemplo que proporcionó.

class CustomObject { 

    private string _id; 

    public CustomObject(string id) { 
     _id=id; 
    } 

    public static bool operator ==(CustomObject lhs, CustomObject rhs) { 
     if (ReferenceEquals(lhs, rhs)) { return true; } 
     if (ReferenceEquals(lhs, null)) { return false; } 
     if (ReferenceEquals(rhs, null)) { return false; } 
     return lhs._id == rhs._id; 
    } 

    public static bool operator !=(CustomObject lhs, CustomObject rhs) { 
     return !(lhs == rhs); 
    } 

    public static bool operator ==(CustomObject lhs, string rhs) { 
     if (ReferenceEquals(lhs, rhs)) { return true; } 
     if (ReferenceEquals(lhs, null)) { return false; } 
     if (ReferenceEquals(rhs, null)) { return false; } 
     return lhs._id == rhs; 
    } 

    public static bool operator !=(CustomObject lhs, string rhs) { 
     return !(lhs==rhs); 
    } 

} 

CustomObject o = null; 
if (o == null) { 
    Console.WriteLine("I don't compile."); 
} 
+0

Gracias, gran respuesta. En el proyecto que mencioné, usan este mismo tipo de verificación nula en tipos de concreto también. –

+1

Pero debo agregar que cualquiera que haya hecho esto con una clase debe ser perseguido y asesinado por el monstruo de humo. Pondría mucha tensión y confusión indebida en cualquiera que use el tipo. – Josh

+1

Solo otro caso: la conversión nula explícita también es necesaria cuando se utiliza el operador condicional "?:" (O el operador ternario, como yo lo sabía en los viejos tiempos). Ejemplo: DateTime? someVar = 0> 1? DateTime.Now: (DateTime?) Null; – Vinicius

6

No haria un yeso. No hay razón para eso en este caso.

+0

Eso es lo que pensé. Es tan extraño, ya que es un proyecto de código abierto patrocinado por Microsoft para proporcionar las mejores prácticas, y parece que no tiene sentido. –

3

No hay ninguna razón para emitir nulo en el ejemplo dado. Puede ser por legibilidad ... No sé, no haría esto = P

En algunos casos [que no incluye el caso cubierto en este tema] tiene que convertir a INullable antes que usted puede verificar si una variable es nula. De lo contrario, debe usar object == default (TypeOfObject) ...

Cuestiones relacionadas