2011-06-03 19 views
5

He leído la siguiente afirmación con respecto a la comparación de los tipos de valores de C# en C# en profundidad, segunda edición varias veces.Comparaciones directas de los tipos de valores de C#

página 77,

Cuando un parámetro de tipo no está restringida (no hay restricciones se aplican a él), puede utilizar == y! = Operadores, pero sólo para comparar un valor de ese tipo con nula. No puede comparar dos valores de tipo T entre sí.

...

Cuando un parámetro de tipo está limitado a ser un tipo de valor, == y! = No se puede utilizar con él en absoluto.

Si entiendo (yo no lo creo) de manera correcta, que básicamente me dice que no se puede uso == o! = Para comparar dos tipos de valor. ¿Por qué por qué?

Será mejor si se puede dar un ejemplo simple para este caso. ¿Puede alguien darme una pequeña idea de lo que el párrafo anterior trata de transmitir?

+2

Sospecho que esto es para evitar confusiones con la sobrecarga del operador, ya que un operador == sobrecargado no se usaría cuando el parámetro de tipo genérico es un tipo de valor. Sin embargo, puede usar Object.Equals, que tipos de valores de buen comportamiento implementarán y que tendrán el mismo comportamiento que == (para tipos de buen comportamiento). –

+1

@ Dan Bryant, no es solo para evitar confusiones. No hay garantía de que un tipo de valor admita los operadores == y! =, Y * no podemos usar la implementación System.Object para los tipos de valor, porque la igualdad de referencia de prueba solo funciona en las instancias encuadradas. * Bueno, podríamos en teoría especificar que los operandos estén enmarcados para usar la verificación de igualdad de referencia, pero que la expresión siempre sería falsa, lo cual es claramente inútil. – phoog

+0

@phoog, el 'Objeto.Equals' estático realmente llamará a la implementación Equals del Objeto (incluso si es un tipo de valor encuadrado), por lo que es una forma válida de comparar los tipos de valores pares. También maneja la comparación de null con tipos de valores. 'Object.ReferenceEquals' fuerza explícitamente a que el cheque sea para igualdad de referencia, lo que puede ser útil en casos donde un tipo de referencia prevalece sobre el operador de igualdad, pero tiene un error para el caso de comparación nula (He encontrado esto antes con un tercero party API.) –

Respuesta

7

Simplemente significa esto cuando constreñir a un tipo de valor (segundo párrafo)

static bool TryToCompare<T>(T first, T second) where T : struct 
{ 
    return first == second; // not legal 
    return first.Equals(second); // legal 
} 

Sin la restricción de tipo valor en el genérico, también se dice que este (primer párrafo)

static bool TryToCompare<T>(T first, T second) 
{ 
    return first == second; // not legal 
    return first == null; // legal 
    return first.Equals(second); // legal 
} 

Si restringe T a un tipo de referencia, puede salirse con la suya usando ==

static bool TryToCompare<T>(T first, T second) where T : class 
{ 
    return first == second; // legal 
    return first == null; // legal 
    return first.Equals(second); // legal 
} 
+0

el primer ejemplo en su segunda función falla b/c no tenemos ninguna restricción en T y T puede ser struct o clase. ¿Es eso correcto? -thx – q0987

+1

Más o menos. No hay garantía de que un tipo de valor 'T' defina el operador' == '. Para obtener más información sobre este tema, le sugiero que vea esta pregunta y la respuesta principal: http://stackoverflow.com/questions/5808057/operator-cant-be-applied-to-type-t –

+0

+1: básicamente solo use '==' y '! =' contra constantes. Si no me equivoco, también puede usar 'default (T)' para la evaluación. De lo contrario, uso 'Equals()'. – IAbstract

0

Los objetos no son comparables porque una comparación que usa == está probando si la referencia es la misma (la dirección de la memoria). Normalmente usarías if (string1.Equals (string2)).

Algo que no entiendo es que he visto circunstancias donde == funciona con cadenas y circunstancias en las que no.

+0

De un POV de resultados, '==' y 'string1.Equals (string2)' no deberían ser diferentes. Se calculan de diferentes maneras, pero para cadenas cortas, 'Igual' tiene una ligera ventaja de velocidad. Buen artículo aquí: http://www.dotnetperls.com/string-equals – keyboardP

+0

En cadenas, comienza a ver resultados "inesperados" cuando las comparaciones se realizan contra los objetos de cadena * como *. Considere 'cadena x =" UNO "; string y = string.Format ("ON {0}", "E"); bool b = x == y; bool c = (objeto) x == (objeto) y; '' b' será verdadero, 'c' será falso. Sin embargo, cambie 'y' para que sea' string y = "ONE"; ', y ahora' c' también será verdadero. –

+0

Si la referencia a cualquiera de los operandos de cadena tiene un tipo de objeto en tiempo de compilación, entonces == se compilará a una verificación de igualdad de referencia. Si ambas son referencias de tipo cadena, obtendrá la implementación de cadena del operador. – phoog

Cuestiones relacionadas