Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why "long value" equals to null is allowed?

Tags:

c#

.net

When I was debugging a few lines of code and asking me why on earth it wasn't working I have stumbled on this situation ...

if(answer.AnswerID == null) 
{
    // do something
}

When in fact it should be this way:

if(answer == null)
{
    // do something
}
  • answer is an object of the type Answer - a class.
  • AnswerID is a property of type long.

The weird thing is that if you try something like this:

long myLongValue = null;

The compiler will show you an error:

Connot convert null to long ...

So my question is: Why did I not get a compile error when I was trying to compare a long type with null?

EDITED

This question IS NOT about nullable types.

I'm asking WHY .NET allows me to compare a long variable with null. I'm talking about long type and not about long? type.

like image 989
Felipe Miosso Avatar asked Jan 14 '14 10:01

Felipe Miosso


People also ask

Can a long be null?

Primitive data types cannot be null . Only Object data types can be null .

Can long be set to null?

If you have declared the data type of Plate number as long, then obviously its initial value will be '0' and not 'null'. So, if you try to increment, it will run without any issues.

Why value is getting null?

A NULL value in a table is a value in a field that appears to be blank. A field with a NULL value is a field with no value. It is very important to understand that a NULL value is different than a zero value or a field that contains spaces.

Can we assign null to long in C#?

The compiler will show you an error: Connot convert null to long ...


2 Answers

As @Tim pointed out, you won't get an error for the following code:

long foo = 42;

if (foo == null) { }

You'll get a warning instead:

The result of the expression is always 'false' since a value of type 'long' is never equal to 'null' of type 'long?'.

This gives a warning instead of an error because of lifted operators, defined in the C# language specification as such:

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.

The "underlying operator" in this case is the predefined value type long's == operator:

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise.

Because foo is implicitly converted ("Predefined implicit conversions that operate on non-nullable value types can also be used with nullable forms of those types.") and the null literal is also implicitly converted ("An implicit conversion exists from the null literal to any nullable type."), the expression:

(long)foo == null

Becomes:

(long?)foo == (long?)null

Which, given foo is of type long and thus always has a value, always returns false and won't even apply long's == operator.

I'm not entirely sure, but I suspect this to exist to enable comparison between nullable and non-nullable values without explicit casting:

long? foo = 42;
long bar = 42;

Console.WriteLine(foo == bar); // true

foo = null;
Console.WriteLine(bar == foo); // false

If this wasn't handled by the language as specified above, you'd get "Operator == cannot be applied to operands of type long? and long", because Nullable<T> doesn't have an == operator, and long doesn't have an == operator accepting a long?.

like image 123
CodeCaster Avatar answered Sep 30 '22 15:09

CodeCaster


It will compile and it will even execute because the compiler evaluates the == and promotes the long to long? because that is the closest match to an == implementation that exists.

This is indeed not the best of behaviors, it's kind of like VB :-)

like image 9
Roy Dictus Avatar answered Sep 30 '22 14:09

Roy Dictus