O operador condicional não pode converter implicitamente?

Estou um pouco perplexo com essa pequena peculiaridade do C #:

Dadas variables:

Boolean aBoolValue; Byte aByteValue; 

As seguintes compilações:

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

Mas isso não vai:

 aByteValue = aBoolValue ? 1 : 0; 

Erro diz: “Não é possível converter implicitamente o tipo ‘int’ para ‘byte’.”

E claro, essa monstruosidade irá compilar:

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

Oque esta acontecendo aqui?

EDITAR:

Usando o VS2008, C # 3.5

Esta é uma pergunta bastante freqüente.

Em C #, quase sempre raciocinamos de dentro para fora. Quando você vê

 x = y; 

nós sabemos qual é o tipo de x, qual é o tipo de y, e se o tipo de y é uma atribuição compatível com x. Mas nós não usamos o fato de que sabemos qual é o tipo de x quando estamos trabalhando no tipo de y.

Isso porque pode haver mais de um 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 

Precisamos ser capazes de descobrir o tipo de uma expressão sem saber para o que ela está sendo atribuída. Digite informações que saem de uma expressão, não em uma expressão.

Para calcular o tipo da expressão condicional, calculamos o tipo de consequência e as expressões alternativas, escolha o mais geral dos dois tipos e isso se torna o tipo da expressão condicional. Portanto, no seu exemplo, o tipo da expressão condicional é “int” e não é uma constante (a menos que a expressão de condição seja constante verdadeira ou constante falsa). Como não é uma constante, você não pode atribuí-la ao byte; o compilador raciocina unicamente dos tipos, não dos valores, quando o resultado não é uma constante.

A exceção a todas essas regras é expressões lambda, nas quais as informações de tipo fluem do contexto para o lambda. Acertar essa lógica foi muito difícil.

Estou usando o VS 2005, para e posso reproduzir, para bool e booleano, mas não para verdade

  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 ;) 

A solução mais simples parece ser este casting

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

Assim, sim, parece que o operador ternário está fazendo com que as constantes “consertem” seus tipos como ints e desativam a conversão de tipo implícita que, de outra forma, você obteria de constantes que se encheckboxm no tipo menor.

Eu posso não ter uma ótima resposta para você, mas se você fizer isso em muitos lugares, você pode declarar:

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

e apenas essas variables. Você pode usar o const se for local para o projeto.

EDIT: usando readonly não faria sentido – estes não são sempre destinados a mudar.