Consider the following code:
DateTime t = DateTime.Today;
bool isGreater = t > null;
With Visual Studio 2010 (C# 4, .NET 4.0), I get the following warning:
warning CS0458: The result of the expression is always 'null' of type 'bool?'
This is incorrect; the result is always false
(of type bool
):
Now, the struct DateTime overloads the >
(greater than) operator. Any non-nullable struct (like DateTime) is implicitly convertible to the corresponding Nullable<>
type. The above expression is exactly equivalent to
bool isGreater = (DateTime?)t > (DateTime?)null;
which also generates the same wrong warning. Here the >
operator is the lifted operator. This works by returning false if HasValue
of any of its two operands is false
. Otherwise, the lifted operator would proceed to unwrap the two operands to the underlying struct, and then call the overload of >
defined by that struct (but this is not necessary in this case where one operand does not HasValue
).
Can you reproduce this bug, and is this bug well-known? Have I misunderstood something?
This is the same for all struct types (not simple types like int
, and not enum types) which overload the operator in question.
(Now if we use ==
instead of >
, everything ought to be entirely similar (because DateTime also overloads the ==
operator). But it's not similar. If I say
DateTime t = DateTime.Today;
bool isEqual = t == null;
I get no warning ☹ Sometimes you see people accidentally check a variable or parameter for null, not realizing that the type of their variable is a struct (which overloads ==
and which is not a simple type like int
). It would be better if they got a warning.)
Update: With the C# 6.0 compiler (based on Roslyn) of Visual Studio 2015, the incorrect message with isGreater
above is changed into a CS0464 with a correct and helpful warning message. Also, the lack of warning with isEqual
above is fixed in VS2015's compiler, but only if you compile with /features:strict
.