13

Usando Casting null doesn't compile como fuente de inspiración, y desde el comentario de Eric Lippert:¿Por qué esta conversión implícita de int a uint funciona?

Eso demuestra un caso interesante. "uint x = (int) 0;" sería tener éxito a pesar de que int no es implícitamente convertible a uint.

Sabemos que esto no funciona, porque object no se pueden asignar a string:

string x = (object)null; 

Pero esto, aunque intuitivamente que no deben:

uint x = (int)0; 

Por qué hace el compilador permite este caso, cuando int no es implícitamente convertible a uint?

+1

Supongo que la misma razón 'unidad x = 0' funciona. '0' es un int firmado a menos que especifique' unit x = 0U'. – vcsjones

+6

Probablemente 6.1.9 de la especificación y el descuento del int cast, porque 0 ya es un int. Aunque generalmente un int no es implícitamente convertible a uint (6.1.2), se puede convertir una * expresión constante * de tipo int. –

+0

¿Qué valor tiene '0' implícitamente como expresión constante entonces?¿El compilador simplemente ignora el molde explícito '(int)' y trata a '0' como una constante' uint'? – Yuck

Respuesta

26

Las conversiones constantes enteras son tratadas como muy especiales por el lenguaje C#; aquí está la sección 6.1.9 de la especificación:

Una expresión constante de tipo int se puede convertir al tipo sbyte, byte, short, ushort, uint o ulong, siempre que el valor de la constante-expresión está dentro de la rango del tipo de destino. Una expresión constante de tipo long se puede convertir a tipo ulong, siempre que el valor de la expresión constante no sea negativo.

Esto le permite hacer cosas como:

byte x = 64; 

que de otro modo requeriría una conversión explícita fea:

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

+1 Muy bueno. Sin embargo, me habría ido con '// yuck';) – Yuck

+0

Entonces, en el caso de' uint i = (int) 0; ', ¿el compilador simplemente ignora el elenco? ¿O es solo que el resultado de emitir una expresión constante es en sí mismo una expresión constante? – dlev

+3

@dlev: este último. Lanzar una expresión constante de tipo int a int sigue siendo una expresión constante. –

9

El siguiente código Wil error con el mensaje "No se puede convertir implícitamente el tipo 'int' a 'uint'. Existe una conversión explícita (¿falta un yeso?)"

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

Y esto fallará con : "valor constante '-1' no se puede convertir a un 'uint'"

uint x = (int)-1; 

Así que la única razón por uint x = (int)0; funciona es porque el compilador ve que 0 (o cualquier otro valor> 0) es una constante de tiempo de compilación que se puede convertir en uint

+0

¿Básicamente optimiza el descarte ya que no es necesario para un literal? – BoltClock

+3

@BoltClock Una expresión constante se puede convertir en el tiempo de compilación para que el yeso realmente se elimine. –

2

En compiladores generales tienen 4 etapas en la que se convierte el código. El texto está tokenizado> Se procesan los tokens> Se genera un AST + linking> el AST se convierte al idioma de destino.

La evaluación de constantes como números y cadenas se produce como un primer paso y el compilador probablemente trate 0 como un token válido e ignora el molde.

Cuestiones relacionadas