Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a null value in .NET DateTime guaranteed to be less than a real value?

Tags:

.net

nullable

Perhaps my Google-Fu has failed me, but I haven't been able to determine if comparing a nullable in .NET will always be less than something else.

I've got some code similar to this

MyClass findLatest(List<MyClass> items){
    DateTime? latest_tstamp = null;
    MyClass latest_item = null;
    foreach(var item in items){
        if (latest_tstamp < item.tstamp){
            latest_tstamp = item.tstamp;
            latest_item = item;
        }
    }
    return latest_item;
}

It's seemed to work in the few limited cases I've tried (item.tstamp is declared DateTime? tstamp as well, of course).

Is this guaranteed behavior?

Conclusion(?)

Based on the answers (and Jon Skeet's [answer on another question]), I've gone with the following check:

if (item.tstamp != null &&
    (latest_tstamp == null || latest_tstamp < item.tstamp)){
    // do stuff
}
like image 967
Wayne Werner Avatar asked Jul 11 '12 16:07

Wayne Werner


3 Answers

This is behavior is guaranteed by the C# specification. The result of < on nullable value-types is false if any of them is null. Reference types on the other hand might exhibit different behavior.

Still I wouldn't recommend using this. It's hard to understand this code. I'd prefer an explicit null check, or just a boolean flag isFirstElement instead of using a nullable in the first place.

7.2.7 Lifted operators

Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:

...

  • For the relational operators
         <   >   <=   >=
    a lifted form of an operator exists if the operand types are both non-nullable value types and if the result type is bool. The lifted form is constructed by adding a single ? modifier to each operand type. The lifted operator produces the value false if one or both operands are null. Otherwise, the lifted operator unwraps the operands and applies the underlying operator to produce the bool result.

(Quoted from C# Language Specification Version 3.0)

like image 184
CodesInChaos Avatar answered Oct 07 '22 16:10

CodesInChaos


Quote from MSDN:

When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal). It is important not to assume that because a particular comparison returns false, the opposite case returns true. In the following example, 10 is not greater than, less than, nor equal to null. Only num1 != num2 evaluates to true.

An equality comparison of two nullable types that are both null evaluates to true.

like image 25
Lucero Avatar answered Oct 07 '22 17:10

Lucero


In this case it will never be true. A comparison between nullable values where one of the values is null always produces false. Hence the if comparison will never be true here and latest_item will never be set to a value

like image 43
JaredPar Avatar answered Oct 07 '22 15:10

JaredPar