2009-11-13 11 views
25

Estaba escribiendo en un código donde necesitaba leer el valor de fecha de un control de calendario en mi página (Ajax toolkit: calendar extensor).System.DateTime? vs System.DateTime

El código de abajo:

DateTime newSelectedDate = myCalendarExtender.SelectedDate; 

da el siguiente error:

Cannot implicitly convert type 'System.DateTime?' to 'System.DateTime'. An explicit conversion exists (are you missing a cast?) 

Sin embargo, mediante la inserción de un elenco que puedo conseguir el código para trabajar:

DateTime newSelectedDate = (DateTime)myCalendarExtender.SelectedDate; // works fine! 

El 'Selec La propiedad tedDate 'para el control de calendario (Ajax toolkit) describe el tipo de datos como' System.DateTime? ' ... claramente el '?' tiene algo que ver con todo esto.

¿Qué está sucediendo exactamente cuando un tipo de datos contiene este símbolo (?) ... Supuse que podría aplicar la propiedad 'SelectedDate' directamente en una variable de tipo 'DateTime' sin fundir.

Gracias

Respuesta

44

? significa que el tipo es anulable. Para obtener más detalles, consulte, por ejemplo, MSDN

Nullable es un envoltorio soportado por el compilador alrededor de los tipos de valores que permiten que los tipos de valores se vuelvan nulos.

Para acceder al valor DateTime, es necesario hacer lo siguiente:

DateTime? dateOrNull = myCalendarExtender.SelectedDate; 
if (dateOrNull != null) 
{ 
    DateTime newSelectedDate = dateOrNull.Value; 
} 
+0

@Marek - que prefieren la url prima? Mis disculpas por la edición entonces. –

+0

@Jeff: Agregó el bloque de código en su edición también, por lo que probablemente no fue un cambio intencional ... solo que ya tenía la pantalla de edición abierta antes de su edición. – Powerlord

+0

@Jeff: Lo siento, fue involuntario. No sabía que editaste la url, mis ediciones sobrescribieron las tuyas. – Marek

19

DateTime? es lo mismo que Nullable<DateTime> Es decir: una instancia de DateTime? puede contener 'NULL', mientras que una instancia de DateTime hace no. (Esto es cierto para todo valor -. Tipos desde .NET 2.0 un tipo de valor no puede contener NULL, pero, a partir de .NET 2.0, los tipos de valor anulables están soportados a través de la Nullable<T> constructo (o la forma abreviada)

?. usted puede obtener el valor de DateTime y ponerlo en DateTime al hacer esto:?

DateTime? someNullableDate; 
DateTime myDate; 

if(someNullableDate.HasValue) 
    myDate = someNullableDate.Value; 

Otra forma más concisa para obtener el valor de un anulable, se usando el operador nulo coalescencia:

DateTime myDate = someNullableDate?? default(DateTime); 
+1

Esta es una solución mucho mejor que la respuesta. –

10

El control de calendario devuelve un Nullable <DateTime> (¿taquigrafía en C# es DateTime?) En su propiedad SelectedDate, ya que DateTime es una estructura. El valor nulo permite que el control tenga un estado "sin fecha seleccionada". Por lo tanto, deberá verificar si el valor anulable tiene un valor antes de poder usarlo.

 
var nullable = myCalendarExtender.SelectedDate; 
var newSelectedDate = (nullable.HasValue) ? nullable.Value : SomeDefaultValue; 

EDIT: Aún más concisa, gracias al comentario de Josh:

 
var newSelectedDate = myCalendarExtender.SelectedDate ?? SomeDefaultValue; 

me gusta!

+2

Puede simplificar esto con lo siguiente: var newDate = nullable ?? someDefault; – Josh

+0

+1 Josh para concisión –

+1

sí, use '??', esta es la razón por la que lo tenemos. – TheSean

10

Una solución mucho mejor y la OMI la mejor característica de todos con la clase anulable

DateTime newSelectedDate = myCalendarExtender.SelectedDate.GetValueOrDefault(); 
+0

Yo diría que esta es la solución mucho mejor. –

2

Puede utilizar el ?? operador para trabajar con elementos nulables de una manera muy concisa en C#. Vea mi comentario sobre la respuesta de Travis para una forma más corta de expresar el concepto "si no es nulo, luego utilícelo, use algún valor predeterminado". Ambos hacen la misma cosa.

-1
var Endtime = DateTime.Now(); 
DateTime startTime = item.REPORT_TIME.HasValue ? item.REPORT_TIME.Value : Endtime; 

Medios: el tipo de elemento.item.REPORT_TIME es system.DateTime?
howerver el tipo de startTime es system.DateTime; por lo que el código puede cambiarlo como

`var Endtime = DateTime.Now; var = horaInicio item.REPORT_TIME.HasValue Convert.ToDateTime (item.REPORT_TIME.HasValue):? Fin

`

+1

¿Puedes formatear tu código y explicarlo con más detalles? –

+0

esta es la primera vez que da la respuesta, la cambiaré. Gracias por su consejo. –

Cuestiones relacionadas