C# Okay with Comparing Value Types to Null

C# okay with comparing value types to null

This is legal because operator overload resolution has a unique best operator to choose. There is an == operator that takes two nullable ints. The int local is convertible to a nullable int. The null literal is convertible to a nullable int. Therefore this is a legal usage of the == operator, and will always result in false.

Similarly, we also allow you to say "if (x == 12.6)", which will also always be false. The int local is convertible to a double, the literal is convertible to a double, and obviously they will never be equal.

Why can I compare an enum with null?

The enum is casted to a nullable version of it before comparison, so it can and will evaluate. The result is however always the same.

That is why the compiler warns you:

Warning CS0472 The result of the expression is always 'false' since a value of type 'Color' is never equal to 'null' of type 'Color?'

Although the comparison is useless, the compiler doesn't prevent you to perform it. Just like it doesn't prevent your to make a if(false) { }, which is just as useless.

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

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.

How do nullable types handle null values with comparison operators?

Does anyone have concrete information on how C# handles comparisons with Nullable types when one side of the comparison is null?

Yes - the C# language specification, section 7.3.7. In this case, it's a relational operator:

For the relation operators < > <= >= a lifted form of an operator exists if the operand types are both non-nullable 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.

There are similarly detailed sections for other operators.

When in doubt about how some aspect of the language works (and whether it's guaranteed or implementation-specific), the C# language specification should be your first port of call.

How does comparison operator works with null int?

According to MSDN - it's down the page in the "Operators" section:

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 !=

So both a > b and a < b evaluate to false since a is null...

C# comparing reference and value types with null

In short, you can't compare like this, ever...

In regards to if (a.Right == b.Right == null)

It compiles because you can compare a non-nullable value types with null and it's always false.

  1. a.Right == b.Right // bool

  2. bool == null //will be lifted and always equal false (see below)

To know the reason why you'll have to visit the specs and understand lifted operators

12.4.8 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

  • For the equality 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 considers two null values equal, and a null
value unequal to any non-null value
. If both operands are non-null,
the lifted operator unwraps the operands and applies the underlying
operator to produce the bool result.

In regards to if(aa == bb == 0) you can't compare bool with an int, there is no implicit conversion to bool

  1. aa == bb // bool

  2. bool == 0 // there is no implicit conversion to bool

Comparing 'int' to 'null' compiles

When the comparison is made, the compiler tries to make it so both operands of the comparison have compatible types if possible.

It had an int value and a constant null value (with no particular type). The only compatible type between the two values is int? so they are coerced to int? and compared as int? == int?. Some int value as an int? is definitely non-null and null is definitely null. The compiler realizes that and since a non-null value is not equal to a definite null value, the warning is given.

Wrong compiler warning when comparing struct to null

You are correct: this is a bug in Visual Studio. The C# 4.0 standard (§ 7.3.7 Lifted operators) has this to say:

For the relational operators

<  >  <=  >=

[…] The lifted operator produces the value false if one or both operands are null.

And in fact, in MonoDevelop, you get the following warning instead:

The result of comparing type System.DateTime with null is always false.

How to compare an object to null in c#

Okay, the comment's giving it away:

Ok, in doing this, I noticed that when I hover over the variable in debugging mode, the value is null, but when it ISNT working, the value is {null}... What does {null} mean?

That suggest it's actually an array (or possibly another collection type) containing a single null reference, e.g.

object obj = new object[] { null };

The value of obj is not a null reference, hence it doesn't go into the body of the if statement.

How you should handle this depends on what you're trying to achieve. Do you really need obj to be statically typed as just object?

Why is comparing a struct to NULL legal in C#?

Fails to compile for me:

struct Foo { }

class Program
{
static void Main( string[] args )
{
var f = new Foo();
if( f == null ) { }
}
}

Error 1 Operator '==' cannot be applied to operands of type 'ConsoleApplication3.Foo' and 'null'



Related Topics



Leave a reply



Submit