Em muitos contextos em que um método ou argumento de operador não é do tipo necessário, o compilador C # tentará executar uma conversão implícita de tipo. Se o compilador puder fazer com que todos os argumentos satisfaçam seus operadores e métodos adicionando conversões implícitas, ele o fará sem reclamar, embora em alguns casos (especialmente com testes de igualdade!) Os resultados possam ser surpreendentes.
Além disso, cada tipo de valor como int
ou short
realmente descreve um tipo de valor e um tipo de objeto (*). Existem conversões implícitas para converter valores em outros tipos de valores e converter qualquer tipo de valor em seu tipo de objeto correspondente, mas os diferentes tipos de objetos não são implicitamente conversíveis entre si.
Se alguém usa o ==
operador para comparar um short
e um int
, o short
será convertido implicitamente a um int
. Se o seu valor numérico for igual ao valor de int
, o valor int
para o qual foi convertido será igual ao valor int
de comparação. Se alguém tentar usar o Equals
método no short para compará-lo com um int
, no entanto, a única conversão implícita que satisfaria uma sobrecarga do Equals
método seria a conversão para o tipo de objeto correspondente a int
. Quando short
perguntado se ele corresponde ao objeto transmitido, ele observará que o objeto em questão é um int
e não um short
e, portanto, concluirá que ele não pode ser igual.
Em geral, embora o compilador não se queixe, deve-se evitar comparar coisas que não são do mesmo tipo; se alguém estiver interessado em saber se a conversão de coisas em uma forma comum daria o mesmo resultado, deve-se realizar essa conversão explicitamente. Considere, por exemplo,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
Existem três maneiras pelas quais se pode comparar um int
a um float
. Alguém pode querer saber:
- O
float
valor mais próximo possível da int
correspondência é float
?
- O número inteiro faz parte da
float
correspondência int
?
- Faça o
int
e float
represente o mesmo valor numérico.
Se alguém tentar comparar um int
e float
diretamente, o código compilado responderá à primeira pergunta; se é isso que o programador pretendia, no entanto, estará longe de ser óbvio. Alterar a comparação para (float)i == f
deixaria claro que o primeiro significado era intencional ou (double)i == (double)f
faria com que o código respondesse à terceira pergunta (e deixasse claro que era o que pretendia).
(*) Mesmo que a especificação C # considere um valor do tipo, por exemplo, System.Int32
como um objeto do tipo System.Int32
, essa visão é contrariada pelo requisito de que um código seja executado em uma plataforma cuja especificação considere valores e objetos como habitando universos diferentes. Além disso, se T
é um tipo de referência e x
é a T
, uma referência do tipo T
deve poder fazer referência x
. Assim, se uma variável v
do tipo Int32
contiver um Object
, uma referência do tipo Object
deve poder manter uma referência v
ou seu conteúdo. De fato, uma referência do tipo Object
seria capaz de apontar para um objeto contendo dados copiados v
, mas não para v
si próprio nem para seu conteúdo. Isso sugeriria que nemv
nem seu conteúdo é realmente um Object
.