2011-05-05 21 views
10

vi el siguiente código,C# - ¿Es esto comprobando necesario "obj es persona && obj = null!"

public override bool Equals(object obj) 
{ 
    // From the book http://www.amazon.co.uk/Pro-2010-NET-4-0-Platform/dp/1430225491 
    // Page 254! 
    if (obj is Person && obj != null) 
... 
} 

Basado en mi conocimiento, creo que el código debe ser reescrita como sigue:

public override bool Equals(object obj) 
{ 
    if (obj is Person) 
... 
} 

¿Es correcto?

Basado en http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.80%29.aspx

An es expresión se evalúa a verdadero si la expresión proporcionada es no nulo, y el objeto proporcionado se puede convertir al tipo proporcionado sin causar una excepción a ser lanzado.

Creo que la comprobación adicional para null NO es necesaria en absoluto. En otras palabras, ese código "obj! = Null" nunca debería ser golpeado en absoluto.

Gracias

// // Actualizado

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication2 
{ 
    class Employee 
    { 
     public static void CheckIsEmployee(object obj) 
     { 
      if (obj is Employee) 
      { 
       Console.WriteLine("this is an employee"); 
      } 
      else if (obj == null) 
      { 
       Console.WriteLine("this is null"); 
      } 
      else 
      { 
       Console.WriteLine("this is Not an employee"); 
      } 
     } 
    } 

    class NotEmployee 
    { } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Employee e = new Employee(); 

      Employee.CheckIsEmployee(e); 

      Employee f = null; 
      Employee.CheckIsEmployee(f); 

      NotEmployee g = new NotEmployee(); 
      Employee.CheckIsEmployee(g); 
     } 
    } 
} 

resultados de salida:

this is an employee 
this is null 
this is Not an employee 

Respuesta

8

Mi preferencia sería utilizar la palabra clave as.

public override bool Equals(object obj) 
{ 
    var objectToCompare = obj as Person; 
    if (objectToCompare == null) 
     return false; 
    ... 
} 

La ventaja es que más tarde en el método, tiene una instancia escrita a máquina (objectToCompare) con el que hacer sus comparaciones.

Tiene razón en su evaluación de que obj is Person devolverá falso si obj no se deriva de Person o si obj es nulo y por lo tanto obj is Person && obj != null es redundante; solo necesita obj is Person si usa ese estilo. Técnicamente, podría haber una ganancia de rendimiento fraccionario comprobando nulo primero, pero la ganancia sería insignificante.

+0

Depende de la definición de 'is' ;-) En el caso de .NET,' as' ejecuta internamente un 'is' y establece el resultado en' null' si 'is' es falso. La solución de jlew es más óptima si a veces se puede esperar 'null'. –

+0

@Eric J: D. La razón para usar 'as' es principalmente tener el uso de la instancia tipeada más tarde. Entonces, en la solución de 'jlew', (presumiblemente) necesitarías lanzar' obj' como 'Persona' después de que hayas determinado que no era nulo para que puedas hacer el resto de la evaluación de Igual. Guarda una o dos líneas de código para el mismo resultado. – Thomas

1

Su versión parece más correcta para mí. No será una Persona a menos que sea no nula, por lo que obj! = Null es redundante.

8

Funcionalmente es correcto, pero es más rápido comprobar la nulidad que hacer una verificación de tipo de tiempo de ejecución, por lo que es mejor que primero verifique nulo en la mayoría de las situaciones. De esta forma, si obj es nulo, no se incurrirá en la sobrecarga de la verificación del tipo de tiempo de ejecución.

+0

por favor vea mi publicación actualizada. – q0987

+2

@ q0987, Bueno, acabo de hacer una prueba de rendimiento rápido y resulta ser esencialmente el mismo rendimiento de cualquier manera. Cualquiera de las dos operaciones se puede realizar cientos de millones de veces por segundo, por lo que probablemente no valga la pena preocuparse desde el punto de vista del rendimiento. – jlew

1

Una referencia a una persona todavía puede ser una referencia nula, por lo que técnicamente sí, se requieren ambos controles.

Me gusta la respuesta de Thomas sobre cómo manejar ambos controles a la vez. null as MyClass == null, y myClassInstance as OtherClass == null, por lo que con una comprobación del objeto emitido de forma segura ha confirmado ambas condiciones, y como dijo, tiene una referencia fuertemente tipada para trabajar a partir de ese momento.

Existe una interesante discusión sobre la diferencia en niveles bajos entre is y as operaciones con palabras clave. Google "Es como es o es como" (estoy teniendo problemas con Internet en este momento). Resulta que funcionan de manera muy similar en el nivel de IL.

+1

+1 Por hacer que busque "Es como es o es como". http://blogs.msdn.com/b/ericlippert/archive/2010/09/16/is-is-as-or-is-as-is.aspx?PageIndex=2#comments – Thomas

Cuestiones relacionadas