En muchos contextos donde un método o argumento de operador no es del tipo requerido, el compilador de C # intentará realizar una conversión de tipo implícita. Si el compilador puede hacer que todos los argumentos satisfagan sus operadores y métodos agregando conversiones implícitas, lo hará sin quejarse, aunque en algunos casos (¡especialmente con pruebas de igualdad!) Los resultados pueden ser sorprendentes.
Además, cada tipo de valor tal como into shortrealmente describe tanto un tipo de valor como un tipo de objeto (*). Existen conversiones implícitas para convertir valores a otros tipos de valores y para convertir cualquier tipo de valor a su tipo de objeto correspondiente, pero los diferentes tipos de objetos no son implícitamente convertibles entre sí.
Si uno usa el ==operador para comparar ay shortan int, el shortse convertirá implícitamente en an int. Si su valor numérico es igual al del int, el intal que se convirtió será igual intal que se compara. Sin embargo, si se intenta utilizar el Equalsmétodo en corto para compararlo con un int, la única conversión implícita que satisfaría una sobrecarga del Equalsmétodo sería la conversión al tipo de objeto correspondiente int. Cuando shortse le pregunta si coincide con el objeto pasado, observará que el objeto en cuestión es intmás bien que un shorty, por lo tanto, concluirá que no puede ser igual.
En general, aunque el compilador no se quejará, se debe evitar comparar cosas que no son del mismo tipo; Si uno está interesado en saber si la conversión de cosas a una forma común daría el mismo resultado, debería realizar dicha conversión explícitamente. Considere, por ejemplo,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
Hay tres formas en que uno podría comparar una inta una float. Uno podría querer saber:
- ¿Coincide el
floatvalor más cercano posible con intel float?
- ¿La parte del número entero
floatcoincide con el int?
- Haz
inty floatrepresenta el mismo valor numérico.
Si uno intenta comparar inty floatdirectamente, el código compilado responderá la primera pregunta; si eso es lo que pretendía el programador, sin embargo, estará lejos de ser obvio. Cambiar la comparación a (float)i == fdejaría en claro que se pretendía el primer significado, o (double)i == (double)fharía que el código respondiera a la tercera pregunta (y dejaría claro que eso era lo que se pretendía).
(*) Incluso si la especificación de C # considera un valor de tipo, por ejemplo, System.Int32como un objeto de tipo System.Int32, tal opinión se contradice con el requisito de que un código se ejecute en una plataforma cuya especificación considere valores y objetos que habitan universos diferentes. Además, si Tes un tipo de referencia, y xes un T, entonces una referencia de tipo Tdebería poder referirse x. Por lo tanto, si una variable vde tipo Int32contiene una Object, una referencia de tipo Objectdebería poder contener una referencia a vo su contenido. De hecho, una referencia de tipo Objectpodría apuntar a un objeto que contiene datos copiados v, pero no a vsí mismo ni a su contenido. Eso sugeriría que ningunovni su contenido es realmente un Object.