Reputation: 155592
I'm using int
as an example, but this applies to any value type in .Net
In .Net 1 the following would throw a compiler exception:
int i = SomeFunctionThatReturnsInt();
if( i == null ) //compiler exception here
Now (in .Net 2 or 3.5) that exception has gone.
I know why this is:
int? j = null; //nullable int
if( i == j ) //this shouldn't throw an exception
The problem is that because int?
is nullable and int
now has a implicit cast to int?
. The syntax above is compiler magic. Really we're doing:
Nullable<int> j = null; //nullable int
//compiler is smart enough to do this
if( (Nullable<int>) i == j)
//and not this
if( i == (int) j)
So now, when we do i == null
we get:
if( (Nullable<int>) i == null )
Given that C# is doing compiler logic to calculate this anyway why can't it be smart enough to not do it when dealing with absolute values like null
?
Upvotes: 5
Views: 2023
Reputation: 47452
Odd ... compiling this with VS2008, targetting .NET 3.5:
static int F()
{
return 42;
}
static void Main(string[] args)
{
int i = F();
if (i == null)
{
}
}
I get a compiler warning
warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
And it generates the following IL ... which presumably the JIT will optimize away
L_0001: call int32 ConsoleApplication1.Program::F()
L_0006: stloc.0
L_0007: ldc.i4.0
L_0008: ldc.i4.0
L_0009: ceq
L_000b: stloc.1
L_000c: br.s L_000e
Can you post a code snippet?
Upvotes: 3
Reputation: 28416
The 2.0 framework introduced the nullable value type. Even though the literal constant "1" can never be null, its underlying type (int) can now be cast to a Nullable int type. My guess is that the compiler can no longer assume that int types are not nullable, even when it is a literal constant. I do get a warning when compiling 2.0:
Warning 1 The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
Upvotes: 1
Reputation: 18340
It ought to be a compile-time error, because the types are incompatible (value types can never be null). It's pretty sad that it isn't.
Upvotes: 0
Reputation: 155592
The warning is new (3.5 I think) - the error is the same as if I'd done 1 == 2
, which it's smart enough to spot as never true.
I suspect that with full 3.5 optimisations the whole statement will just be stripped out, as it's pretty smart with never true evaluations.
While I might want 1==2
to compile (to switch off a function block while I test something else for instance) I don't want 1==null
to.
Upvotes: 0
Reputation: 21470
I don't think this is a compiler problem per se; an integer value is never null, but the idea of equating them isn't invalid; it's a valid function that always returns false. And the compiler knows; the code
bool oneIsNull = 1 == null;
compiles, but gives a compiler warning: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'
.
So if you want the compiler error back, go to the project properties and turn on 'treat warnings as errors' for this error, and you'll start seeing them as build-breaking problems again.
Upvotes: 3
Reputation: 8255
Compiler still generates warning when you compare non-nullable type to null, which is just the way it should be. May be your warning level is too low or this was changed in recent versions (I only did that in .net 3.5).
Upvotes: 1