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

StackOverflow https://stackoverflow.com/questions/220250

Pregunta

Tengo curiosidad por saber por qué falla un elenco implícito en ...

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

y por qué tengo que realizar un reparto explícito

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

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

¿Fue útil?

Solución

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

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

Si X e Y son del mismo tipo, entonces este es el tipo de 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 el tipo de expresión y se produce un error en tiempo de compilación.

Otros consejos

También me molesta que no pueda inferir el tipo según la asignación, especialmente cuando es un tipo de valor. Hay razones, sin embargo, cuando te metes en jerarquías de objetos.

Si " ResultOfSomeCalc () " devolvió 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 compilador no existe para que sustituya un Nullable como denominador común.

Observe que estas variantes funcionan, y puede ayudarlo a comprender:

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

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

Espero que esto ayude.

Parece que esto es algo que el compilador debería poder resolver por sí mismo, pero hay otra forma de hacerlo, utilizando la palabra clave predeterminada. Puede que sea lo más mínimo menos feo que el reparto:

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

Este uso de los valores predeterminados no parece estar bien documentado, pero sí funciona. Al menos evita que tengas que ensuciar tu código con valores mágicos (considero que nulo / cero / falso / etc. son valores mágicos).

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

Si su función devuelve int, entonces el compilador 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 "?: & Quot; debe tener el mismo tipo o debe ser convertible al mismo tipo a través de una conversión implícita.

Cambie el tipo de retorno de ResultOfSomeCalc a int ?, o tendrá que tener la conversión en la expresión nula.

Haga que el tipo de retorno de ResultOfSomeCalc () de su función sea nullabel int like (int?)
¿En t? someValue = (int?) SomeCondition? ResultofSomeCalc (): (int?) Null;

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top