<p>I'm using <code>int</code> as an example, but this applies to any value type in .Net</p>

<p>In .Net 1 the following would throw a compiler exception:</p>

<pre><code>int i = SomeFunctionThatReturnsInt();

if( i == null ) //compiler exception here
</code></pre>

<p>Now (in .Net 2 or 3.5) that exception has gone.</p>

<p>I know why this is:</p>

<pre><code>int? j = null; //nullable int

if( i == j )   //this shouldn't throw an exception
</code></pre>

<p>The problem is that because <code>int?</code> is nullable and <code>int</code> now has a implicit cast to <code>int?</code>. The syntax above is compiler magic.  Really we're doing:</p>

<pre><code>Nullable&lt;int&gt; j = null; //nullable int

//compiler is smart enough to do this
if( (Nullable&lt;int&gt;) i == j)   

//and not this
if( i == (int) j)
</code></pre>

<p>So now, when we do <code>i == null</code> we get:</p>

<pre><code>if( (Nullable&lt;int&gt;) i == null )
</code></pre>

<p>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 <code>null</code>?</p>

[{'answer_id': 62724, 'author': 'ima', 'author_id': 5733, 'author_profile': 'https://Stackoverflow.com/users/5733', 'pm_score': 1, 'selected': False, 'text': '<p>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).</p>\n'}, {'answer_id': 62747, 'author': 'Rob Walker', 'author_id': 3631, 'author_profile': 'https://Stackoverflow.com/users/3631', 'pm_score': 2, 'selected': False, 'text': "<p>Odd ... compiling this with VS2008, targetting .NET 3.5:</p>\n\n<pre><code>static int F()\n{\n    return 42;\n}\n\nstatic void Main(string[] args)\n{\n    int i = F();\n\n    if (i == null)\n    {\n    }\n}\n</code></pre>\n\n<p>I get a compiler warning</p>\n\n<pre><code>warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'\n</code></pre>\n\n<p>And it generates the following IL ... which presumably the JIT will optimize away</p>\n\n<pre><code>L_0001: call int32 ConsoleApplication1.Program::F()\nL_0006: stloc.0 \nL_0007: ldc.i4.0 \nL_0008: ldc.i4.0 \nL_0009: ceq \nL_000b: stloc.1 \nL_000c: br.s L_000e\n</code></pre>\n\n<p>Can you post a code snippet?</p>\n"}, {'answer_id': 62775, 'author': 'Steve Cooper', 'author_id': 6722, 'author_profile': 'https://Stackoverflow.com/users/6722', 'pm_score': 3, 'selected': True, 'text': "<p>I don't think this is a compiler problem <em>per se</em>; 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</p>\n\n<pre><code>bool oneIsNull = 1 == null;\n</code></pre>\n\n<p>compiles, but gives a compiler warning: <code>The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '&lt;null&gt;'</code>.</p>\n\n<p>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.</p>\n"}, {'answer_id': 63027, 'author': 'Keith', 'author_id': 905, 'author_profile': 'https://Stackoverflow.com/users/905', 'pm_score': 0, 'selected': False, 'text': "<p>The warning is new (3.5 I think) - the error is the same as if I'd done <code>1 == 2</code>, which it's smart enough to spot as never true.</p>\n\n<p>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.</p>\n\n<p>While I might want <code>1==2</code> to compile (to switch off a function block while I test something else for instance) I don't want <code>1==null</code> to.</p>\n"}, {'answer_id': 63099, 'author': 'DrPizza', 'author_id': 2131, 'author_profile': 'https://Stackoverflow.com/users/2131', 'pm_score': 0, 'selected': False, 'text': "<p>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.</p>\n"}, {'answer_id': 63326, 'author': 'Michael Meadows', 'author_id': 7643, 'author_profile': 'https://Stackoverflow.com/users/7643', 'pm_score': 1, 'selected': False, 'text': '<p>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:</p>\n\n<p>Warning 1   The result of the expression is always \'false\' since a value of type \'int\' is never equal to \'null\' of type \'int?\'</p>\n'}]
['https://Stackoverflow.com/questions/62606', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/905/']