Il s'agit d'une question assez fréquemment posée.
En C#, nous raisonnons presque toujours de l'intérieur vers l'extérieur. Lorsque vous voyez
x = y;
nous déterminons quel est le type de x, quel est le type de y, et si le type de y est compatible avec x. Mais nous n'utilisons pas le fait que nous connaissons le type de x lorsque nous calculons le type de y.
C'est parce qu'il peut y avoir plus d'un 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
Nous besoin de être capable de déterminer le type d'une expression sans en sachant à quoi elle est affectée. Type de flux d'informations out d'une expression, et non en une expression.
Pour déterminer le type de l'expression conditionnelle, nous déterminons le type de la conséquence et des expressions alternatives, nous choisissons le type le plus général des deux, et cela devient le type de l'expression conditionnelle. Ainsi, dans votre exemple, le type de l'expression conditionnelle est "int", et ce n'est pas une constante (sauf si l'expression conditionnelle est constante true ou constante false). Puisque ce n'est pas une constante, vous ne pouvez pas l'assigner à byte ; le compilateur raisonne uniquement à partir des types, et non à partir des valeurs, lorsque le résultat n'est pas une constante.
L'exception à toutes ces règles est constituée par les expressions lambda, où les informations de type fait du contexte dans le lambda. Obtenir une logique correcte a été très difficile.