2009-12-13 12 views
34

Lo siguiente no se compila:de prueba para la igualdad en el valor predeterminado

public void MyMethod<T>(T value) 
{ 
    if (value == default(T)) 
    { 
     // do stuff 
    } 
} 

error: Operator '==' cannot be applied to operands of type 'T' and 'T'

No puedo utilizar value == null porque T puede ser una estructura.
No puedo usar value.Equals(default(T)) porque value puede ser null.
¿Cuál es la forma correcta de probar la igualdad del valor predeterminado?

+2

respondió al comentario; y para información, 'EqualityComparer ' es la implementación estándar utilizada por el BCL, por ejemplo en 'Dictionary <,>'. –

+2

posible duplicado de http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp – nawfal

Respuesta

53

Para evitar boxeo para struct/Nullable<T>, me gustaría utilizar:

if (EqualityComparer<T>.Default.Equals(value,default(T))) 
{ 
    // do stuff 
} 

Esto es compatible con cualquier T que implementan IEquatable<T>, utilizando object.Equals como copia de seguridad, y se ocupa de null etc. (y levantó operadores para Nullable<T>) automáticamente. También hay Comparer<T>.Default que maneja las pruebas de comparación. Maneja T que implementan IComparable<T>, volviendo a IComparable - manejando de nuevo null y operadores levantados.

+0

¿Está diciendo que 'EqualityComparer . Default.Equals' tiene un mejor rendimiento que' Object.Equals', o que daría un valor correcto en algún caso que 'Object.Equals' no? – Greg

+9

Mejor rendimiento (menos boxeo); considere 'T = int'; para llamar a 'object.Equals' tiene que encapsular' value' y 'default (T)' - eso es dos asignaciones extra de montón + GC. Usando 'EqualityComparer ' tiene 3 implementaciones subyacentes diferentes - 'clase',' Nullable 'y' struct' - puede hacer todo (incluso pruebas 'null') sin ** ningún ** boxeo. El trabajo de averiguar qué implementación usar solo se hace una vez por tipo y en caché, por lo que es muy rápido. –

+0

¡Gracias, Marc! Tu explicación es maravillosa – Greg

21

¿Qué hay de

object.Equals(value, default(T)) 
+0

Sabía que debería ser simple. Gracias. – Greg

+1

+1. Probado. Funciona correctamente con varios tipos: 'MyMethod (0); MyMethod (nulo); MyMethod (null); '- en cada caso devuelve verdadero. –

Cuestiones relacionadas