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 intou shortrealmente 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 shorte um int, o shortserá convertido implicitamente a um int. Se o seu valor numérico for igual ao valor de int, o valor intpara o qual foi convertido será igual ao valor intde comparação. Se alguém tentar usar o Equalsmétodo no short para compará-lo com um int, no entanto, a única conversão implícita que satisfaria uma sobrecarga do Equalsmétodo seria a conversão para o tipo de objeto correspondente a int. Quando shortperguntado se ele corresponde ao objeto transmitido, ele observará que o objeto em questão é um inte não um shorte, 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 inta um float. Alguém pode querer saber:
- O
floatvalor mais próximo possível da intcorrespondência é float?
- O número inteiro faz parte da
floatcorrespondência int?
- Faça o
inte floatrepresente o mesmo valor numérico.
Se alguém tentar comparar um inte floatdiretamente, 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 == fdeixaria claro que o primeiro significado era intencional ou (double)i == (double)ffaria 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.Int32como 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 Tdeve poder fazer referência x. Assim, se uma variável vdo tipo Int32contiver um Object, uma referência do tipo Objectdeve poder manter uma referência vou seu conteúdo. De fato, uma referência do tipo Objectseria capaz de apontar para um objeto contendo dados copiados v, mas não para vsi próprio nem para seu conteúdo. Isso sugeriria que nemvnem seu conteúdo é realmente um Object.