En C #, ¿por qué un operador condicional no puede convertir implícitamente a un tipo anulable?

Tengo curiosidad de por qué un elenco implícito falla en …

int? someValue = SomeCondition ? ResultOfSomeCalc() : null; 

y por qué tengo que realizar un lanzamiento explícito en su lugar

 int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null; 

Me parece que el comstackdor tiene toda la información que necesita para tomar una decisión implícita de lanzamiento, ¿no?

La sección relevante de la especificación de C # 3.0 es 7.13, el operador condicional:

El segundo y tercer operandos del operador?: Controlan el tipo de expresión condicional. Deje que X e Y sean los tipos del segundo y tercer operandos. Entonces,

Si X e Y son del mismo tipo, entonces este es el tipo del condicional. De lo contrario, si existe una conversión implícita (§6.1) de X a Y, pero no de Y a X, entonces Y es el tipo de expresión condicional. De lo contrario, si existe una conversión implícita (§6.1) de Y a X, pero no de X a Y, entonces X es el tipo de expresión condicional. De lo contrario, no se puede determinar ningún tipo de expresión y se produce un error en tiempo de comstackción.

También me molesta que no pueda inferir el tipo basado en la asignación, especialmente cuando se trata de un tipo de valor. Sin embargo, hay razones cuando te metes en jerarquías de objetos.

Si “ResultOfSomeCalc ()” devolviera un “int?”, Entonces esto funcionaría . C # necesita averiguar el tipo independientemente de lo que esté a la izquierda de la tarea. Entonces le está diciendo que devolverá un nulo o un int. Y la lógica en el comstackdor no existe para que sustituya un Nullable como un denominador común.

Tenga en cuenta que estas variantes SI funcionan, y puede ayudarlo a comprender:

 object someValue = true ? new Nullable(ResultOfSomeCalc()) : null; object someValue = true ? (int?)ResultOfSomeCalc() : null; 

Espero que esto ayude.

Seguramente parece que esto es algo que el comstackdor debería poder descifrar por sí mismo, pero hay otra forma de hacerlo, utilizando la palabra clave predeterminada. Puede ser un poco menos feo que el elenco:

 int? someValue = SomeCondition ? ResultofSomeCalc() : default(int?); 

Este uso del valor predeterminado no parece estar bien documentado, pero funciona. Al menos te evita tener que ensuciar tu código con valores mágicos (sostengo que null / zero / false / etc. Son de hecho valores mágicos).

Ver también ¿Por qué este código no es válido en C #?

Si su función ResultofSomeCalc () devuelve int? entonces esto funcionará

Si su función devuelve int, el comstackdor emite la advertencia: El tipo de expresión condicional no se puede determinar porque no hay una conversión implícita entre ‘int’ y ”
Supongo que eso es lo que estás viendo. Ambas expresiones en el operador condicional “?:” Deben tener el mismo tipo, o deben ser convertibles al mismo tipo a través de un molde implícito.

¿Cambia el tipo de devolución de ResultOfSomeCalc a int ?, o tendrá que tener el molde en la expresión nula.

Haga que su función ResultOfSomeCalc () ‘s return type como nullabel int like (int?)
¿En t? someValue = (int?) SomeCondition? ResultofSomeCalc (): (int?) Null;