views:

606

answers:

6

Why do I get this warning in C# with Visual Studio 2010?

"Unreachable expression code detected"

from the following code (DateTime.Now underlined in green squiggly):

public DateTime StartDate
{
  get
  {
    DateTime dt = (DateTime)ViewState["StartDate"];
    return ((dt == null) ? DateTime.Now : dt);
  }
}
+30  A: 

Because a DateTime struct can never be null.

If you're expecting a possible null value, you have to use a nullable DateTime struct. You could also use the null-coalescing operator instead of the conditional operator as well:

public DateTime StartDate
{
    get
    {
        DateTime? dt = (DateTime?)ViewState["StartDate"];
        return dt ?? DateTime.Now;
    }
}

Or you could do it as a one-liner (as in the comments):

public DateTime StartDate
{
    get { return (DateTime)(ViewState["StartDate"] ?? DateTime.Now); }
}
Justin Niessner
So what happens if the "StartDate" key doesn't exist?
Blam
@Blam: In ASP.NET, if the ViewState key does not exists, you get `null`. I often express the same thing as @Justin with a one-liner: `return (DateTime)(ViewState["StartDate"] ?? DateTime.Now);`. Works like a charm.
kbrimington
@Blam: I was just in the process of asking that myself! @Justin: great solution, thanks!
JohnB
@Blam: if StartDate doesn't exist dt will be null and the coalescing operator (??) will then return the right side (DateTime.Now)
Ricardo Villamil
I didn't think `return dt ?? DateTime.Now;` would compile, since `dt` is `Nullable<DateTime>` and the return type is `DateTime`. However, that gets compiled to the equivalent of `return dt.HasValue ? dt.GetValueOrDefault() : DateTime.Now;`. Interesting.
Anthony Pegram
@Anthony: The rules for determining exactly what the result type of the null coalescing operator is are pretty complicated, but usually result in the sensible thing. After all, the intention of the operator is to *eliminate nulls*, so we want to go to the non-nullable type if we can possibly get away with it. See the language spec for details.
Eric Lippert
+3  A: 

That could be because DateTime is a struct (value type) & not a reference type.
Hence, comparing it with null will always be false.

shahkalpesh
+1  A: 

DateTime cannot be null

akonsu
+3  A: 

DateTime is a value type, so it can never be null. Therefore, the test for == null evaluates to a constant false at compile time, so half of the ?: will never be reached at runtime.

dthorpe
A: 

DateTime is not nullable, so its value will never be null.

Basser
+3  A: 

The answers given already -- that a non-nullable value type will never be null, and therefore the comparison is known to return false at compile time -- are correct, you might be wondering about the obvious follow-up question: why is this even legal? That question has been asked many times on SO; the short version is that C# provides a "lifted" equality operator for every struct that provides an equality operator on the non-nullable type (if a lifted one does not exist already of course.)

That is to say, because DateTime provides an == operator, the compiler automatically generates an == operator on DateTime?, and that operator is applicable in your case.

Eric Lippert