Tipos que aceptan valores NULL y el operador ternario:¿Por qué es `?10:nulo` prohibido?[duplicar]

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

Pregunta

Me acabo de encontrar con un error extraño:

private bool GetBoolValue()
{
    //Do some logic and return true or false
}

Luego, en otro método, algo como esto:

int? x = GetBoolValue() ? 10 : null;

Simple, si el método devuelve verdadero, asigna 10 a Nullableint X.De lo contrario, asigne nulo al anulable En t.Sin embargo, el compilador se queja:

Error 1 No se puede determinar el tipo de expresión condicional porque no hay una conversión implícita entre int y <null>.

¿Me estoy volviendo loco?

¿Fue útil?

Solución

El compilador primero intenta evaluar la expresión de la derecha:

GetBoolValue() ? 10 : null

El 10 es un int literal (no int?) y null esta bien, null.No hay ninguna conversión implícita entre esos dos, de ahí el mensaje de error.

Si cambia la expresión de la derecha a una de las siguientes, se compila porque hay una conversión implícita entre int? y null (#1) y entre int y int? (#2, #3).

GetBoolValue() ? (int?)10 : null    // #1
GetBoolValue() ? 10 : (int?)null    // #2
GetBoolValue() ? 10 : default(int?) // #3

Otros consejos

Prueba esto:

int? x = GetBoolValue() ? 10 : (int?)null;

Básicamente lo que está sucediendo es que el operador condicional es incapaz de determinar el "tipo de retorno" de la expresión. Desde el compilador decide implictitly que 10 es un int entonces decide que el tipo de retorno de esta expresión será un null también. Desde un Nullable<int> no puede ser int? (el tercer operando del operador condicional) se queja.

Por la fundición <=> a un <=> le estamos diciendo al compilador explícitamente que el tipo de retorno de esta expresión será un <=>. Que podría haber la misma facilidad fundido el <=> a <=> así y tenía el mismo efecto.

Prueba esto:

int? result = condition ? 10 : default(int?);

Por cierto, la implementación de Microsoft del compilador de C # en realidad recibe el análisis del tipo de operador condicional equivocada de una manera muy sutil e interesante (para mí). Mi artículo en él es problemas de inferencia de tipos, primera parte .

Pruebe uno de los siguientes:

int? x = GetBoolValue() ? (int?)10 : null;

int? x = GetBoolValue() ? 10 : (int?)null;

El problema es que el operador ternario está infiriendo tipo basado en su primera parametrización 10 ... en este caso, que es un int, no un int anulable.

Es posible que tenga mejor suerte con:

int? x = GetBoolValue() (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;

La razón por la que ves esto es porque detrás de las escenas que está utilizando anulable y hay que decir que su C # "nulo" es una instancia nula de anulable.

Sólo tiene que añadir un reparto explict.

int? x = GetBoolValue() ? 10 : (int?)null;

Es el operador ternario que se confunde -. El segundo argumento es un número entero y también lo es el tercer argumento exspected a ser un número entero, también, y nulo no encaja

Es porque el compilador determina el tipo de operador condicional por su segundo y tercer operando, no por lo que se asigna el resultado a. No hay reparto directo entre un número entero y una referencia nula de que el compilador puede utilizar para determinar el tipo.

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