2009-11-13 4 views
25

J'écrivais à un code où j'avais besoin de lire la valeur de date d'un contrôle de calendrier dans ma page (Ajax toolkit: extension de calendrier).System.DateTime? vs System.DateTime

Le code ci-dessous:

DateTime newSelectedDate = myCalendarExtender.SelectedDate; 

donne l'erreur suivante:

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

Cependant, en insérant un cast je peux obtenir le code pour:

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

Le 'Selec La propriété tedDate 'du contrôle de calendrier (Ajax toolkit) décrit le type de données en tant que' System.DateTime? ' ... clairement le '?' a quelque chose à voir avec tout cela. Que se passe-t-il exactement lorsqu'un type de données contient ce symbole (?) ... J'ai supposé pouvoir appliquer la propriété 'SelectedDate' directement dans une variable de type 'DateTime' sans conversion.

Merci

Répondre

44

? signifie que le type est nullable. Pour plus de détails, voir par ex. MSDN

Nullable est une enveloppe supportée par le compilateur autour de types de valeurs qui permet aux types de valeurs pour devenir nulle.

Pour accéder à la valeur DateTime, vous devez effectuer les opérations suivantes:

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

@Marek - vous préférez l'url brut? Mes excuses pour l'édition alors. –

+0

@ Jeff: Il a ajouté le bloc de code dans son édition aussi, donc il est fort probable n'a pas été un changement intentionnel ... juste qu'il avait déjà l'écran d'édition ouverte avant votre édition. – Powerlord

+0

@Jeff: Désolé, c'était involontaire. Je ne savais pas que vous avez édité l'url, mon édition a écrasé le vôtre. – Marek

19

DateTime? est le même que Nullable<DateTime> C'est: une instance de DateTime? peut contenir « NULL », alors qu'une instance de DateTime ne ne pas. (Ceci est vrai pour toute valeur -. Types depuis .NET 2.0 Un type de valeur ne peut pas contenir NULL, mais, comme de .NET 2.0, les types de valeur nullables sont pris en charge par la construction Nullable<T> (ou le raccourci)

?. vous pouvez obtenir la valeur de DateTime et le mettre dans DateTime en faisant cela:

DateTime? someNullableDate; 
DateTime myDate; 

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

une autre façon de conciser pour obtenir la valeur d'un Nullable, est en utilisant l'opérateur null-coalescent:

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

Ceci est une solution beaucoup plus agréable que la réponse. –

10

Le contrôle Calendar renvoie un Nullable <DateTime> (raccourci en C# est DateTime?) Dans sa propriété SelectedDate, puisque DateTime est une structure. La valeur nulle permet au contrôle d'avoir un état "pas de date sélectionnée". Ainsi, vous devrez vérifier si le nullable a une valeur avant de pouvoir l'utiliser.

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

EDIT: Encore plus concise, grâce au commentaire de Josh:

 
var newSelectedDate = myCalendarExtender.SelectedDate ?? SomeDefaultValue; 

Je l'aime!

+2

Vous pouvez simplifier ceci avec ce qui suit: var newDate = nullable ?? someDefault; – Josh

+0

+1 Josh pour la concision –

+1

oui, s'il vous plaît utilisez '??', c'est pourquoi nous l'avons. – TheSean

10

Une bien meilleure solution et de l'OMI la meilleure caractéristique de tous avec la classe annulable

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

Je dirais que c'est la solution bien soignée. –

2

Vous pouvez utiliser le ?? opérateur de travailler avec des valeurs NULL d'une manière très concise en C#. Voir mon commentaire sur la réponse de Travis pour une façon plus courte d'exprimer le concept «si non null, puis utilisez-le autrement utiliser une valeur par défaut». Ils font tous deux la même chose.

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

Moyens: le type de item.item.REPORT_TIME est system.DateTime?
howerver le type de startTime est system.DateTime; de sorte que le code peut changer comme

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

`

+1

Pouvez-vous s'il vous plaît formater votre code et expliquer avec plus de détails? –

+0

c'est la première fois donner la réponse, je vais le changer. Merci pour votre conseil. –

Questions connexes