Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I allowed to compare a non-nullable type with null? [duplicate]

Possible Duplicate:
C# okay with comparing value types to null

If I try to assign null to a non-nullable type in C#:

System.DateTime time = null;

I'll get a compile-time error:

error CS0037: Cannot convert null to 'System.DateTime' because it is a non-nullable value type

which makes sense. But if compare the same type against null:

System.DateTime time = obtainFromSomewhere();
if( time == null ) {
    //whatever;
}

there's no compile-time error. This doesn't make sense to me - if I can't assign null then why would it ever be null?

Why am I allowed to compare a non-nullable type with null?

like image 919
sharptooth Avatar asked Apr 19 '11 08:04

sharptooth


People also ask

Does HasValue check for null?

The HasValue property returns true if the variable contains a value, or false if it is null. You can only use == and != operators with a nullable type. For other comparison use the Nullable static class.

Can we compare two null values in C#?

Comparing NULL values Since you can't use a equality operator in the WHERE clause (remember, NULL values can't be equated or compared), the right way to compare NULL values is to use the IS and IS NOT operators.

What is a non nullable type?

Nullable variables may either contain a valid value or they may not — in the latter case they are considered to be nil . Non-nullable variables must always contain a value and cannot be nil . In Oxygene (as in C# and Java), the default nullability of a variable is determined by its type.

What is the point of nullable reference types?

Nullable reference types are a compile time feature. That means it's possible for callers to ignore warnings, intentionally use null as an argument to a method expecting a non nullable reference. Library authors should include runtime checks against null argument values.


2 Answers

The reason this works for DateTime, is because DateTime defines it own == operator. Because it does so, it gets a lifted version of the operator which may be used with DateTime?. Since both DateTime and null may be implicitly converted to DateTime?, the comparison compiles but will always evaluate to false at runtime.

Thanks to Matt Ellen for pointing out the fact that my original answer didn't cover the example in the question.

like image 196
Brian Rasmussen Avatar answered Oct 23 '22 10:10

Brian Rasmussen


It's due to Boxing.

DateTime can be boxed as object and thus it becomes a reference which can be compared with null (though it will always be false).

However, an object (null) can't be unboxed back to DateTime, thus it can't be assigned to DateTime.

Example: you could do

object now = DateTime.Now;
bool isNull = now == null

EDIT: As Brian Rasmussen pointed out, I was wrong with the boxing theory. Boxing would only occur if explicitly casted to object like in my example or in (object)DateTime.Now == null.

like image 5
František Žiačik Avatar answered Oct 23 '22 10:10

František Žiačik