El operador condicional no puede transmitir implícitamente?

Estoy un poco perplejo por este pequeño capricho de C #:

Variables dadas:

Boolean aBoolValue; Byte aByteValue; 

Las siguientes comstackciones:

 if (aBoolValue) aByteValue = 1; else aByteValue = 0; 

Pero esto no:

 aByteValue = aBoolValue ? 1 : 0; 

El error dice: “No se puede convertir implícitamente el tipo ‘int’ en ‘byte'”.

Y por supuesto, esta monstruosidad comstackrá:

 aByteValue = aBoolValue ? (byte)1 : (byte)0; 

¿Que está pasando aqui?

EDITAR:

Usando VS2008, C # 3.5

Esta es una pregunta bastante frecuente.

En C #, casi siempre razonamos desde adentro hacia afuera. Cuando veas

 x = y; 

resolvemos cuál es el tipo de x, cuál es el tipo de y, y si el tipo de y es asignación compatible con x. Pero no usamos el hecho de que sabemos cuál es el tipo de x cuando estamos trabajando en el tipo de y.

Eso es porque puede haber más de una x:

 void M(int x) { } void M(string x) { } ... M(y); // y is assigned to either int x or string x depending on the type of y 

Necesitamos poder resolver el tipo de expresión sin saber a qué se está asignando. La información de tipo sale de una expresión, no de una expresión.

Para calcular el tipo de expresión condicional, calculamos el tipo de consecuencia y las expresiones alternativas, seleccionamos el más general de los dos tipos, y eso se convierte en el tipo de expresión condicional. Entonces en su ejemplo, el tipo de expresión condicional es “int”, y no es una constante (a menos que la expresión de condición sea constante verdadera o constante). Como no es una constante, no puedes asignarla a byte; el comstackdor solo razona de los tipos, no de los valores, cuando el resultado no es una constante.

La excepción a todas estas reglas son expresiones lambda, donde la información de tipo fluye del contexto al lambda. Conseguir esa lógica correcta fue muy difícil.

Estoy usando VS 2005, para y puedo reproducir, para bool y booleano, pero no para verdadero

  bool abool = true; Boolean aboolean = true; Byte by1 = (abool ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte' Byte by2 = (aboolean ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte' Byte by3 = (true ? 1 : 2); //Warning: unreachable code ;) 

La solución más simple parece ser este elenco

  Byte by1 = (Byte)(aboolean ? 1 : 2); 

Entonces, sí, parece que el operador ternario está causando que las constantes “arreglen” sus tipos como entradas y deshabiliten la conversión de tipo implícita que de lo contrario obtendría de constantes que se ajustan al tipo más pequeño.

Puede que no tenga una buena respuesta para ti, pero si haces esto en muchos lugares, podrías declarar:

 private static readonly Byte valueZero = (byte)0; private static readonly Byte valueOne = (byte)1; 

y solo estas variables. Puede salirse con la suya si usa const si es local para el proyecto.

EDITAR: el uso de readonly no tiene sentido; estos no siempre tienen la intención de cambiar.