160

Could someone explain why this works in C#.NET 2.0:

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

...but this doesn't:

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

The latter form gives me an compile error "Type of conditional expression cannot be determined because there is no implicit conversion between '<null>' and 'System.DateTime'."

Not that I can't use the former, but the second style is more consistent with the rest of my code.

1
  • 12
    You can save yourself a lot of typing by using DateTime? instead of Nullable<DateTime>. Commented Nov 17, 2008 at 15:24

5 Answers 5

338

The compiler is telling you that it doesn't know how convert null into a DateTime.

The solution is simple:

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

Note that Nullable<DateTime> can be written DateTime? which will save you a bunch of typing.

Sign up to request clarification or add additional context in comments.

5 Comments

Works well enough but now you can't null check foo - it will always have a value. No way around this though - as MojoFilter says "It's because in a ternary operator, the two values must be the same type."
@DilbertDave The information from MojoFilter's post is incorrect.
I'd add that the compiler tries to guess the resulting type of the ternary operation not by looking at the variable to which it is assigned, but by looking at the operands instead. It finds <null> and DateTime and instead of finding the common ancestor type, it just tries to find a conversion between each other. (Extra bit: C# recognizes a <null> type, i.e. the type of every null expression.)
If it's been asked a bunch of times already, where's the duplicate question flag?
@starmandeluxe they all likely point here (at least that I how I got here)
20

FYI (Offtopic, but nifty and related to nullable types) we have a handy operator just for nullable types called the null coalescing operator

?? 

Used like this:

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

4 Comments

How does this answer his question??
Nick is trying to assign null to foo if some condition is true. The null coalesce will assign DateTime(0) to value if foo is null. The two are completely unrelated.
Hence the FYI, offtopic but a nice thing to know.
Ah, OK. It is pretty useful to know.
8

It's because in a ternary operator, the two values must resolve to the same type.

1 Comment

No, they don't have to be the same type. Either the second operand must be implicitly convertible to the type of the third operand or the other way around.
3

I know this question was asked in 2008 and it is now 5 years later but the answer marked as an answer does not satisfy me. The real answer is that DateTime is a struct, and as a struct it is not compatible with null. You have two ways of solving that:

First is to make null compatible with DateTime (for instance, cast null to DateTime? as the gentleman with 70 upvotes suggests, or cast null to Object or to ValueType).

The second is to make the DateTime compatible with null (for instance, cast DateTime to DateTime?).

Comments

3

Another solution similar to the accepted is to use C#'s default keyword. While defined using generics, it is actually applicable to any type.

Example usage applied to the OP's question:

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

Example usage with the current accepted answer:

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

Also, by using default, you do not need to specify the variable as nullable in order to assign it a null value. The compiler will auto-assign the specific variable-type's default value and no error will be encountered. Example:

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

3 Comments

Not true, default(DateTime) is not null, it is "1.1.0001 0:00:00", the same as new DateTime(0).
@IllidanS4, I didn't say that it's equal to null, only that by using default() you can assign it to a nullable value (as MSDN states). The examples I show demonstrate the versatility that it can be used with Nullable<DateTime>, DateTime?, and simply DateTime. If you believe this to be incorrect, can you provide a PoC where these fail?
Well, the questioner wanted to store null in the variable, not default(DateTime), so this is misleading at best. This is not "versatile" as you imply, since the expression as a whole has still the same type - DateTime, and you can replace default(DateTime) with new DateTime() and it will do the same thing. Maybe default(DateTime?) is what you meant, since that is actually equal to null.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.