c# - usar - El operador condicional no puede transmitir implícitamente?
operadores lógicos validos para c# (3)
Estoy un poco perplejo por este pequeño capricho de C #:
Variables dadas:
Boolean aBoolValue;
Byte aByteValue;
Las siguientes compilaciones:
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 compilará:
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 compilador 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.