13

Utilizzando Casting null doesn't compile come fonte di ispirazione, e dal commento di Eric Lippert:Perché questa conversione implicita da int a uint funziona?

che dimostra un caso interessante. "uint x = (int) 0;" sarebbe riuscire anche se int non è implicitamente convertibile in uint.

Sappiamo questo non funziona, perché object non può essere assegnato a string:

string x = (object)null; 

ma questo, anche se intuitivamente non dovrebbe:

uint x = (int)0; 

Perché fa il compilatore permettono questo caso, quando int non è implicitamente convertibile in uint?

+1

Suppongo che la stessa ragione "unità x = 0" funzioni. '0' è un int firmato a meno che non si specifichi' unit x = 0U'. – vcsjones

+6

Probabilmente 6.1.9 delle specifiche e attualizzazione del cast int, perché 0 è già un int. Mentre generalmente un int non è convertibile in modo implicito in uint (6.1.2), può essere convertita una * espressione costante * di tipo int. –

+0

Quale valore ha '0' implicitamente come espressione costante allora?Il compilatore ignora semplicemente il cast esplicito '(int)' e considera '0' come una costante' uint'? – Yuck

risposta

26

Integer conversioni costanti sono trattati come molto speciale dal linguaggio C#; ecco sezione 6.1.9 della specifica:

Una costante espressione di tipo int può essere convertito nel tipo sbyte, byte, short, ushort, uint o ulong, a condizione che il valore della costante-espressione è all'interno intervallo del tipo di destinazione. Un'espressione costante di tipo long può essere convertita in type ulong, purché il valore dell'espressione costante non sia negativo.

Questo ti permette di fare cose come:

byte x = 64; 

che altrimenti richiederebbero una conversione esplicita brutta:

byte x = (byte)64; // gross 
+12

+1 Molto interessante. Sarei andato con '// yuck', però;) – Yuck

+0

Quindi nel caso di' uint i = (int) 0; ', il compilatore ignora semplicemente il cast? O è solo che il risultato del casting di un'espressione costante è di per sé un'espressione costante? – dlev

+3

@dlev: quest'ultimo. La trasmissione di un'espressione costante di tipo int a int è ancora un'espressione costante. –

9

Il codice seguente wil non riuscire con il messaggio "Impossibile convertire implicitamente il tipo 'int' a 'uint'. Esiste una conversione esplicita (che le manca un cast?)"

int y = 0; 
uint x = (int)y; 

E questo non riuscirà con : "valore costante '-1' non può essere convertito in un 'uint'"

uint x = (int)-1; 

Quindi l'unica ragione uint x = (int)0; funziona è perché il compilatore vede che 0 (o qualsiasi altro valore> 0) è una costante di tempo di compilazione che può essere convertito in uint

+0

Quindi fondamentalmente ottimizza il cast in quanto non è necessario per un valore letterale? – BoltClock

+3

@BoltClock Un'espressione costante può essere convertita in fase di compilazione in modo che il cast venga effettivamente rimosso. –

2

In compilatori generali sono 4 passaggi in cui viene convertito il codice. Il testo è tokenizzato> I token vengono analizzati> Viene creato un AST + linking> l'AST viene convertito nella lingua di destinazione.

La valutazione di costanti come numeri e stringhe si verifica come un primo passaggio e il compilatore probabilmente considera 0 come token valido e ignora il cast.