2009-05-06 19 views
10
double? test = true ? null : 1.0; 

En mi libro, esto es lo mismo que¿Por qué este código C# no se compila?

if (true) { 
    test = null; 
} else { 
    test = 1.0; 
} 

Pero la primera línea da este error del compilador:

Type of conditional expression cannot be determined because there is no implicit conversion between ' <null> ' and ' double '.

+0

siempre puede enviar la errata al editor del libro :) o tal vez ya se ha encontrado y está en el libro Errata (normalmente en el sitio web del editor) – balexandre

+3

La expresión "en mi libro" significa "hasta donde yo sé" - no es una referencia a un libro real :-) –

+1

Su posición de que uno es el mismo que el otro no está confirmada ni por la especificación del idioma ni por la implementación; esas dos cosas son muy diferentes! El mensaje de error es correcto; la especificación del lenguaje requiere que la expresión sea implícitamente convertible a double ?, lo que requiere a su vez que la expresión tenga un tipo conocido. La expresión no tiene un tipo conocido, de ahí el error. –

Respuesta

24

Esto ocurre porque el compilador intenta evaluar la instrucción de derecha a izquierda. Esto significa que ve 1.0 y decide que es doble (¿no es doble?) Y luego ve null.

por lo que es evidente que no hay conversión implícita entre double y null (de hecho no hay conversión implícita entre Struct y null).

Lo que puede hacer es decirle explícitamente al compilador que una de las dos expresiones es convertible entre sí.

double? test = true ? null : (double?) 1.0; // 1 
double? test = true ? (double?)null : 1.0;  // 2 
double? test = true ? default(double?) : 1.0; // 3 
double? test = true ? new double?() : 1.0;  // 4 
+0

Gracias, esto funciona! –

7
double? test = true ? (double?)null : 1.0; 

va a funcionar. Esto se debe a que no hay conversión del tipo de la primera expresión (null) al tipo de la segunda expresión (double).

+0

Hehe, la misma respuesta que otra a su alrededor, ahora un confundido :) – leppie

+0

Sorpresa, ambas maneras funcionan :) – leppie

+0

"No se puede convertir nulo en 'doble' porque es un tipo de valor que no admite nulos" –

2

Dado que el compilador no puede encontrar que para nulo y 1.0 para ser compatible, los valores deben ser convertidos al doble ?. Esto necesita ser declarado explícitamente.

double? test = true ? (double?) null : 1.0; 
+0

'null' (literal) ** es ** convertible a' ¿doble? '. De lo contrario, la respuesta aceptada con 'verdadero? null: (double?) 1.0' no podría funcionar. A qué 'null' no es convertible es' doble'. –

+0

@JeppeStigNielsen implícitamente. Estoy totalmente de acuerdo en que es convertible. –

4

El lado izquierdo de la asignación no se utiliza al deducir el tipo de una expresión?:.

En b ? A : B, los tipos de A y B deben ser iguales o uno debe ser implícitamente convertible al otro.

+2

Aquí hay algo de sutileza: ¿es que el tipo de A debe ser convertible al tipo de B, o que A debe ser convertible al tipo de B? ¡El compilador realmente se equivoca! Ver esta publicación http://blogs.msdn.com/ericlippert/archive/2006/05/24/type-inference-woes-part-one.aspx para obtener más información. –

Cuestiones relacionadas