Problema de tipo nullable con: Operador condicional


¿Podría alguien explicar por qué esto funciona en C#.NET 2.0:

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

...pero esto no:

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

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

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

Author: Nick Gotch, 2008-11-17

5 answers

Esta pregunta ya se ha hecho un montón de veces. El compilador le está diciendo 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 Nullable<DateTime> se puede escribir DateTime? lo que le ahorrará un montón de escribir.

 303
Author: Stewart Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 15:34:39

FYI (Offtopic, pero ingenioso y relacionado con tipos nullable) tenemos un operador práctico solo para tipos nullable llamado el operador coalescing null

??

Usado así:

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
 18
Author: FlySwat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-17 15:43:03

Es porque en un operador ternario, los dos valores deben resolver al mismo tipo.

 8
Author: MojoFilter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-29 02:00:30

Otra solución similar a la aceptada es usar C# ' s default palabra clave. 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 respuesta aceptada actual:

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

Además, al usar default, no es necesario especificar la variable como nullable para asignarle un valor null. El compilador asignará automáticamente el valor predeterminado del tipo de variable específico y no habrá error ser encontrado. Ejemplo:

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);
 5
Author: newfurniturey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-04 01:28:33

Sé que esta pregunta se hizo en 2008 y ahora es 5 años más tarde, pero la respuesta marcada como una respuesta no me satisface. La respuesta real es que DateTime es una estructura, y como una estructura no es compatible con null. Usted tiene dos maneras de resolver eso:

Primero es hacer null compatible con DateTime (por ejemplo, cast null to DateTime? como sugiere el caballero con 70 votos positivos, o cast null para Object o ValueType).

El segundo es hacer que la fecha y hora sea compatible con null(por ejemplo, cast DateTime to DateTime?).

 3
Author: Mishax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-07 22:28:40