2008-11-17 23 views
134

Podría alguien explicar por qué esto funciona en C# .NET 2.0:tema tipo anulable con el operador?: Condicional

Nullable<DateTime> foo; 
    if (true) 
     foo = null; 
    else 
     foo = new DateTime(0); 

... pero esto no lo hace:

Nullable<DateTime> foo; 
    foo = true ? null : new DateTime(0); 

La última forma da un error de compilación "No se puede determinar el tipo de expresión condicional porque no hay una conversión implícita entre '<null>' y 'System.DateTime'."

No es que no pueda usar la primera, pero el segundo estilo es más consistente con el resto de mi código.

+11

¿Puede ahorrarse un montón de tipeo usando DateTime? en lugar de Nullable . –

Respuesta

282

Esta pregunta ya ha sido hecha un montón de veces. El compilador le dice que no sabe cómo convertir null en un DateTime.

La solución es simple:

DateTime? foo; 
foo = true ? (DateTime?)null : new DateTime(0); 

Tenga en cuenta que se puede escribir Nullable<DateTime>DateTime? lo que le ahorrará un montón de escribir.

+0

Funciona bastante bien, pero ahora no puede anular la comprobación de foo: siempre tendrá un valor. No hay forma de evitar esto, ya que MojoFilter dice "Es porque en un operador ternario, los dos valores deben ser del mismo tipo". – DilbertDave

+0

@DilbertDave La información de la publicación de MojoFilter es incorrecta. – Mishax

+3

Añadiría que el compilador intenta adivinar el tipo resultante de la operación ternaria no mirando la variable a la que está asignado, sino mirando los operandos. Encuentra '' y 'DateTime' y, en lugar de encontrar el tipo de ancestro común, solo intenta encontrar una conversión entre ellos. (Bit adicional: C# reconoce un tipo '', es decir, el tipo de cada expresión 'null'). – IllidanS4

7

Es porque en un operador ternario, los dos valores deben resolverse con el mismo tipo.

+7

No, no tienen que ser del mismo tipo. O el segundo operando debe ser implícitamente convertible al tipo del tercer operando o al revés. – Mishax

16

FYI (Offtopic, pero ingeniosa y en relación con los tipos anulables) tenemos un operador de mano sólo para tipos anulables llaman el operador coalescente nula

?? 

usados ​​como esto:

// Left hand is the nullable type, righthand is default if the type is null. 
Nullable<DateTime> foo; 
DateTime value = foo ?? new DateTime(0); 
+6

¿Cómo responde esto su pregunta? –

+1

Nick intenta asignar null a foo si alguna condición es verdadera. La coalescencia nula asignará DateTime (0) al valor si foo es nulo. Los dos no tienen ninguna relación. –

+2

De ahí el FYI, algo fuera de lugar pero algo agradable de saber. – FlySwat

6

Otra solución similar al aceptado es usar la palabra clave default de C#. Si bien se define utilizando genéricos, en realidad es aplicable a cualquier tipo.

Ejemplo de uso aplicado a la pregunta del OP:

Nullable<DateTime> foo; 
foo = true ? default(DateTime) : new DateTime(0); 

Ejemplo de uso con la corriente respuesta aceptada:

DateTime? foo; 
foo = true ? default(DateTime) : new DateTime(0); 

Además, mediante el uso de default, no es necesario especificar la variable como nullable para asignarle un valor de null. El compilador asignará automáticamente el valor predeterminado del tipo de variable específico y no se encontrará ningún error. Ejemplo:

DateTime foo; 
foo = true ? default(DateTime) : new DateTime(0); 
+0

Genial, es útil saber –

+8

No es cierto, 'default (DateTime)' no es nulo, es "' 1.1.0001 0: 00: 00' ", lo mismo que' new DateTime (0) '. – IllidanS4

3

Sé que esta pregunta fue hecha en 2008 y ahora es 5 años después pero la respuesta marcada como respuesta no me satisface. La respuesta real es que DateTime es una estructura, y como una estructura no es compatible con null. Hay dos maneras de resolver eso:

Primero es hacer que null sea compatible con DateTime (por ejemplo, lanzar nulo en DateTime? Como sugiere el caballero con 70 votos ascendentes, o anular nulo en Object o ValueType).

La segunda es hacer que DateTime sea compatible con nulo (por ejemplo, lanzar DateTime a DateTime?).

Cuestiones relacionadas