Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Let's take a step back here. The question is confusing and the answers so far are not very clear as to what is going on here.</p> <blockquote> <p>Shouldn't <code>if(1 == null)</code> cause an error?</p> </blockquote> <p>No. That is legal, though dumb. </p> <p>How does the compiler deal with operators like "=="? It does so by applying the <em>overload resolution</em> algorithm.</p> <p>The first thing we must determine is whether this is a "user defined" equality operator or a "built in" equality operator. The left side is a built-in type. The right side has no type at all. Neither of those are user-defined types. Therefore no user-defined operator will be considered. Only built-in operators will be considered.</p> <p>Once we know that, the question is "which built-in operators will be considered?" The built in operators are described in section 7.10 of the spec. They are equality operators on int, uint, long, ulong, decimal, float, double, any enum type, bool, char, object, string and any delegate type.</p> <p>All of the equality operators on value types also have a "lifted" form that takes nullable value types. </p> <p>We must now determine which of those operators are <em>applicable</em>. To be applicable, there must be an implicit conversion from both sides to the operator's type. </p> <p>There is no implicit conversion from int to any enum type, bool, string or any delegate type, so those all vanish from consideration.</p> <p>(There is not an implicit conversion from int to uint, ulong, etc, but since this is a literal one, there is an implicit conversion from 1 to uint, ulong, etc.)</p> <p>There is no implicit conversion from null to any non-nullable value type, so those all disappear too.</p> <p>What does that leave? That leaves the operators on object, int?, long?, uint?, ulong?, double?, float?, decimal? and char? the remaining nullable types. </p> <p>We must now determine which one of those remaining applicable candidates is the unique "best" operator. An operator is better than another operator if its operand type is <em>more specific</em>. "object" is the least specific type, so it is eliminated. Clearly every nullable int can be converted to nullable long, but not every nullable long can be converted to nullable int, so nullable long is less specific than nullable int. So it is eliminated. We continue to eliminate operators in this manner. (In the case of the unsigned types we apply a special rule that says that if int? and uint? are both options then int? wins.)</p> <p>I will spare you the details; ultimately that process leaves nullable int as the unique best operand type.</p> <p>Therefore your program is interpreted as <code>if((int?)1 == (int?)null)</code>, which clearly is legal, and will always be false.</p> <blockquote> <p>Int32 struct doesn't define operator overload method for == operator</p> </blockquote> <p>You are correct. What does that have to do with anything? The compiler is perfectly able to do the analysis without it. I don't understand the relationship you believe this fact has to your question. The fact is about a method that could be defined on a type, the question is about how overload resolution chooses a lifted built-in operator. Those two things are not related because "int" is not a user-defined type. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload