views:

806

answers:

5

Hi guys

I was writing to some code where I needed to read the date value from a Calendar control in my page (Ajax toolkit: calendar extender).

The code below:

DateTime newSelectedDate = myCalendarExtender.SelectedDate;

gives the following error:

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

However, by inserting a cast I can get the code to work:

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

The 'SelectedDate' property for the calendar control (Ajax toolkit) describes the data type as 'System.DateTime?' ... clearly the '?' has something to do with all of this.

What exactly is happening when a data type contains this symbol (?)... I presumed that I could apply the 'SelectedDate' property straight into a variable of type 'DateTime' without casting.

Thanks

+13  A: 

? means that the type is nullable. For details, see e.g. MSDN

Nullable is a compiler-supported wrapper around value types that allows value types to become null.

To access the DateTime value, you need to do the following:

DateTime? dateOrNull = myCalendarExtender.SelectedDate;
if (dateOrNull != null)
{
    DateTime newSelectedDate = dateOrNull.Value;
}
Marek
@Marek - you prefer the raw url? My apologies for the edit then.
Jeff Sternal
@Jeff: He added the code block in his edit as well, so it most likely wasn't an intentional change... just that he already had the edit screen open prior to your edit.
R. Bemrose
@Jeff: Sorry, it was unintentional. I did not know you edited the url, my edit overwrote yours.
Marek
Phew, I wasn't sure whether that sort of thing was out of order or not. :D
Jeff Sternal
Thanks to everybody who replied, it makes soo much more sense now! :)
Dal
FYI, this is also valid in VB.NET now. now we don't have to write `Dim SomeCrap as Nullable(Of Integer)`, we just have to write `Dim SomeCrap as Integer?`
rockinthesixstring
+12  A: 

DateTime? is the same as Nullable<DateTime> That is: an instance of DateTime? can contain 'NULL', whereas an instance of DateTime does not. (This is true for all value - types since .NET 2.0. A Value type cannot contain NULL , but, as from .NET 2.0, nullable value types are supported via the Nullable<T> construct (or the ? shorthand).

You can get the value of DateTime? and put it in DateTime by doing this:

DateTime? someNullableDate;
DateTime myDate;

if( someNullableDate.HasValue )
   myDate = someNullableDate.Value;
Frederik Gheysels
+4  A: 

The Calendar control returns a Nullable<DateTime> (shorthand in C# is DateTime?) in its SelectedDate Property, since DateTime is a struct. The null value allows the Control to have a "no date selected" state. Thus, you'll need to check if the nullable has a value before you can use it.

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

EDIT: Even more concise, thanks to Josh's comment:

var newSelectedDate = myCalendarExtender.SelectedDate ?? SomeDefaultValue;

I like it!

Travis Heseman
You can simplify this with the following: var newDate = nullable ?? someDefault;
Josh Einstein
+1 Josh for concision
Travis Heseman
yes, please use '??', this is why we have it.
TheSean
Or you could skip all of the existence checking yourself as per my answer.
Chris Marisic
@Chris - I agree; however, sometimes I don't want to use the default value of a value type like DateTime... maybe I want DateTime.Today as my default in the evaluation.
Travis Heseman
+4  A: 

A much better solution and IMO the best feature of all with the nullable class

DateTime newSelectedDate = myCalendarExtender.SelectedDate.GetValueOrDefault();
Chris Marisic
+1  A: 

You can use the ?? operator to work with nullables in a very concise way in C#. See my comment on Travis's answer for a shorter way of expressing the "if not null then use it else use some default value" concept. They both do the same thing.

Josh Einstein