2012-01-17 14 views
6

Con la siguiente comprensión sobre el operador de fusión nulo (??) en C#.Fundición implícita del resultado del operador de nulo-coalescencia

int? input = -10; 
int result = input ?? 10;//Case - I 
//is same as: 
int result = input == null? input : 10; // Case - II 

Mientras que, por definición y uso, Case I y Case II son los mismos.

¿Sorprende ver que en el compilador de Case-I es posible convertir textualmente int? to int, mientras que en el Caso-II muestra error: 'Error 1 No se puede convertir implícitamente tipo' int? ' a 'int'"

Qué es lo que me falta acerca operador nulo coalescencia?

Gracias por su interés.

Respuesta

5

para hacer el segundo caso el trabajo con el operador ternario, se puede utilizar la siguiente:.

int result = input != null ? input.Value : 10; 

la propiedad Value del tipo Nullable<T> devuelve el valor T (en este caso, el int)

Otra opción es utilizar Nullable<T>.HasValue:

int result = input.HasValue ? input.Value : 10; 

La construcción myNullableInt != null es sólo el azúcar sintáctica para la HasValue llamada anteriormente.

+0

La primera prueba debe utilizar '=' en lugar de '' == – hvd

+0

@hvd: Absolutamente correcto, culpo a la OP por tener un mal ejemplo. :-P Editado. –

+0

En realidad, creo que tu respuesta es un poco ... ¿una? b: c', donde 'b' es' int? 'y' c' es 'int', es perfectamente válido. Sin embargo, el resultado tiene tipo 'int?', Por lo que necesitaría '(a? B: c) .Value'. O su corrección sugerida, que es perfecta. – hvd

5

Este comportamiento que ha observado para el operador de fusión nula ?? es una función de lenguaje documentado, consulte la sección 7.13 de la Especificación del lenguaje C# 4.0 para obtener más detalles.

The type of the expression a ?? b depends on which implicit conversions are available on the operands. In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a (provided that a has a type), B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type, or A otherwise. Specifically, a ?? b is processed as follows:

  • If A exists and is not a nullable type or a reference type, a compile-time error occurs.

  • If b is a dynamic expression, the result type is dynamic. At run-time, a is first evaluated. If a is not null, a is converted to dynamic, and this becomes the result. Otherwise, b is evaluated, and this becomes the result.

  • Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0, and this becomes the result. Otherwise, b is evaluated and converted to type A0, and this becomes the result.

  • Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. At run-time, a is first evaluated. If a is not null, a becomes the result. Otherwise, b is evaluated and converted to type A, and this becomes the result.

  • Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.

  • Otherwise, a and b are incompatible, and a compile-time error occurs.

Véase la sección 7.14 de por qué el operador condicional a ? b : c funciona de forma diferente.

Download the specification para leer ambos en la integridad en su tiempo libre.

0
int result = input == null ? input : 10; 

Tienes tu condición mixta en el segundo caso - que probablemente significaba:

int result = input != null ? input : 10; 

Ahora bien, esto no se compilará debido a que ambos tipos de uso con el operador ternario deben ser exactamente idéntica (y int? no es lo mismo que int) - se puede utilizar un molde simple como una solución:

int result = input != null ? (int)input : 10; 
-1

Una explantion más concisa:

int? NULL_Int = 1; 
int NORM_Int = 2; 

NULL_Int = NORM_Int; // OK 

NORM_Int = NULL_Int; // NO, you can't assign a null to an int