In molti contesti in cui un argomento di metodo o operatore non è del tipo richiesto, il compilatore C # tenterà di eseguire una conversione di tipo implicita. Se il compilatore può fare in modo che tutti gli argomenti soddisfino i loro operatori e metodi aggiungendo conversioni implicite, lo farà senza lamentarsi, anche se in alcuni casi (specialmente con test di uguaglianza!) I risultati potrebbero essere sorprendenti.
Inoltre, ogni tipo di valore come int
o short
effettivamente descrive sia un tipo di valore che un tipo di oggetto (*). Esistono conversioni implicite per convertire i valori in altri tipi di valori e convertire qualsiasi tipo di valore nel tipo di oggetto corrispondente, ma i diversi tipi di oggetti non sono implicitamente convertibili tra loro.
Se si utilizza l' ==
operatore per confrontare a short
e an int
, il valore short
verrà convertito implicitamente in un int
. Se il suo valore numerico era uguale a quello di int
, il int
a cui è stato convertito sarà uguale int
a cui viene confrontato. Se si tenta di utilizzare il Equals
metodo in breve per confrontarlo con una int
, tuttavia, l'unica conversione implicita che soddisferebbe un sovraccarico del Equals
metodo sarebbe la conversione al tipo di oggetto corrispondente int
. Quando short
viene chiesto se corrisponde all'oggetto passato, osserverà che l'oggetto in questione è int
piuttosto che a short
e quindi conclude che non può essere uguale.
In generale, sebbene il compilatore non se ne lamenti, si dovrebbe evitare di confrontare cose che non sono dello stesso tipo; se uno è interessato al fatto che la conversione di cose in una forma comune darebbe lo stesso risultato, si dovrebbe eseguire esplicitamente tale conversione. Considera, ad esempio,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
Ci sono tre modi in cui si potrebbe voler confrontare un int
a float
. Uno potrebbe voler sapere:
- Il
float
valore più vicino possibile alla int
corrispondenza è float
?
- Il numero intero parte della
float
partita è il int
?
- Esegui
int
e float
rappresentano lo stesso valore numerico.
Se si tenta di confrontare un int
e float
direttamente, il codice compilato risponderà alla prima domanda; se è quello che intendeva il programmatore, tuttavia, sarà tutt'altro che ovvio. Modificando il confronto in (float)i == f
modo da chiarire che era previsto il primo significato, o (double)i == (double)f
farebbe sì che il codice rispondesse alla terza domanda (e chiarire che era quello che era previsto).
(*) Anche se le specifiche C # considerano un valore di tipo System.Int32
come ad esempio un oggetto di tipo System.Int32
, tale vista è contraddetta dal requisito che un codice venga eseguito su una piattaforma le cui specifiche considerano valori e oggetti come abitanti di universi diversi. Inoltre, se T
è un tipo di riferimento ed x
è un T
, allora T
dovrebbe essere possibile fare riferimento a un riferimento di tipo x
. Pertanto, se una variabile v
di tipo Int32
contiene un Object
, un riferimento di tipo Object
dovrebbe essere in grado di contenere un riferimento v
o il suo contenuto. In effetti, un riferimento di tipo Object
sarebbe in grado di indicare un oggetto contenente dati copiati v
, ma non a v
se stesso né al suo contenuto. Ciò suggerirebbe che nessuno dei duev
né il suo contenuto è davvero un Object
.