2011-01-28 9 views
6

estoy tratando lo siguiente:No se puede comparar T value1 con T value2 = default (T). ¿Por qué y cómo hacerlo en C#?

T value1 = el.value; // it's of type T already 
T value2 = default(T); 
if (value1 != value2) // gives the following error: Operator '!=' cannot be applied to operands of type 'T' and 'T' 
{ 
    // ... 
} 

Así que, ¿cómo podría comparar ambos valores? ¿Y por qué ocurre este error?

¡Gracias de antemano!

+0

Asegúrese T ref nula implementa clases de tipo COMPARAR-ish, y el método o clase que define T tiene esas referencias en la declaración. – asawyer

Respuesta

11

También se puede usar una restricción de where T : IEquatable<T> como se ha mencionado Henk, o ignorar las limitaciones y uso:

if (!EqualityComparer<T>.Default.Equals(value1, value2)) 
+0

He visto que el framework usa ese método para probar la igualdad, parece un buen camino a seguir, incluso si es un poco detallado. –

+0

Creo que esta es la forma más simple. ¡Gracias! – Girardi

+0

@Ani: Tienes razón. Olvidé que no existe una interfaz IEquatable no genérica. Editaré –

3

Su rodea clase genérica debe enumerar una restricción: T : IEquatable<T>

Y entonces usted tiene que utilizar value1.Equals(value2)

La razón de todo esto es que no todos los tipos definen operador ==

+0

@ani: Tienes razón, lo eliminé. Figmento de mi imaginación –

+0

Obtendrás una 'NullReferenceException' si' value1' es 'null'. – nicodemus13

2

¿Qué pasa con este ?

if (!value1.Equals(value2)) 

debe ser "objeto cruz" .. :)

+2

Personalmente no me gusta la asimetría de eso. Y, por supuesto, arroja si 'value1 == null' – CodesInChaos

0

Otra cosa que usted podría hacer es definir el operador de comparación (en realidad, el operador de diferencia aquí) para poder comparar elementos del tipo T. Por sí mismo, el compilador no puede saber realmente a qué se refiere cuando escribe value1 != value2, excepto si el operador se ha definido previamente .

Para definir un operador, tendrá que utilizar

public operator!=(T a, T b) { 
    // Comparison code; returns true or false 
} 
+0

Creo que 'T' es un parámetro genérico, por lo que probablemente no sea posible. – CodesInChaos

+0

Eso solo funciona cuando el compilador sabe (exactamente) qué es T. –

1

si utilizar value1.equals (valor2), entonces usted tiene un problema con valores nulos. Mejor:
Object.equals (valor1, valor2)

O para los tipos de referencia (con cuidado):
object.referenceEquals (valor1, valor2)

1

No todos los tipos tienen una implementación por defecto del operador == . Para las clases, la operación predeterminada == es comparar las referencias. Para las estructuras, no existe tal implementación predeterminada.

Puede agregar restricciones de tipo a los parámetros de tipo genérico en C#. Desafortunadamente, no puede definir una restricción que obligue al tipo a tener una implementación del operador ==. Lo mejor que puede hacer es forzar el tipo para que sea una clase: where T: class. An article about type parameter constraints in C#

1

tratar

Equals(value1, value2) 

Una buena manera de evitar

Cuestiones relacionadas