Why is integer == null
a valid boolean expression in C#, if integer
(variable of type int
) is not nullable? (I'm not against it, in fact I like it, but I didn't know it was possible)

- 17,273
- 17
- 89
- 116
-
1You do get a warning, something along the lines of "expression is always false". As to why it's *allowed*, i.e., does not result in a compile time error... I suppose it's for the same reason this is allowed; `while(true)` – Ed S. Jun 18 '13 at 21:46
-
The C# compiler will at compile time optimize this to false when compiled in release mode (a `ldc.i4.0` ends up being in IL). – vcsjones Jun 18 '13 at 21:50
-
1possible duplicate of [C# okay with comparing value types to null](http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null) – Eric Lippert Jun 18 '13 at 22:50
2 Answers
Although int
itself is non-nullable, there's an implicit conversion to int?
, which is nullable.
At that point, if the struct declares an ==
operator with the same type on both sides, then that's lifted to work with nullable types too.
So this doesn't compile:
public struct Foo {}
class Test
{
static void Main()
{
Foo x = new Foo();
if (x == null)
{
...
}
}
}
... but if you give Foo
some operators, it does compile, and without a warning:
public struct Foo
{
public static bool operator ==(Foo x, Foo y) { return true; }
public static bool operator !=(Foo x, Foo y) { return false; }
public override bool Equals(object x) { return false; }
public override int GetHashCode() { return 0; }
}
The operator invocation isn't included in the compiled code, because the compiler knows that the RHS is null.
So code of the form above (where Foo
can be replaced by any non-nullable struct
) has one of three outcomes with the MS C# 5 compiler:
- Warning CS0472 (e.g. with
int
) - Error CS0019 (custom types which don't overload
==
) - Clean compilation (custom types which overload
==
, includingGuid
andDateTime
)
It's not clear to me why the compiler treats some "known" types differently to normal structs though. EDIT: As noted by Eric in comments, this is a known bug in the C# compiler, which is hopefully fixed in Roslyn.

- 1,421,763
- 867
- 9,128
- 9,194
-
-
And trying to create your own implicit operator to convert it to `Nullable
` (eg `public static implicit operator Nullable – Joshua Jun 18 '13 at 21:56(Foo f)`) fails with compiler error [CS0555](http://msdn.microsoft.com/en-us/library/b8xz60wc.aspx). -
10Re: it's not clear why known types are different from user defined types: it is a bug, probably introduced by me when I was refactoring parts of the compiler during C# 3.0. For some unclear reason the bug has never been fixed even though we've known about it for a long time now. I seem to recall I fixed it in Roslyn before I left but I don't recall exactly. – Eric Lippert Jun 18 '13 at 22:45
-
2I also note that this is a duplicate of http://stackoverflow.com/questions/2177850/guid-null-should-not-be-allowed-by-the-compiler/2177971#2177971 and http://stackoverflow.com/a/1972317/88656 – Eric Lippert Jun 18 '13 at 22:47
-
1And this one also has some similar analysis: http://stackoverflow.com/questions/2464097/why-doesnt-the-compiler-at-least-warn-on-this-null/2481017#2481017 – Eric Lippert Jun 18 '13 at 22:49
As Ed mentions there's a warning, but the warning alludes to the reason: int
can be auto-casted to int?
, and null
is a valid value for a variable of type int?
.

- 14,102
- 3
- 28
- 43
-
1
-
You said that backwards. You meant to say that `int` can be *implicitly converted* to `int?`. – Eric Lippert Jun 18 '13 at 22:51
-