Consider the following types:
class A { }
class B { }
interface IC { }
A a = null; // the value doesn't matter - null or anything else, for all three
B b = null;
IC c = null;
The following does not compile:
var x = a == b;
But the following does compile (as I was surprised to discover):
var x = a == c;
As I understand the compiler falls back to using the default == operator, which is defined on object and thus accepts any type for its arguments. The IL looks like this (ignore the details of ldfld):
ldarg.0
ldfld class A a
ldarg.0
ldfld class IC c
ceq
stloc.0
In other words it uses reference equality.
My questions:
-
In terms of language design, why does this make sense? To me it doesn’t, and I consider it a big pitfall.
-
If this is indeed a pitfall, shouldn’t Code Analysis warn us about it? (nope – it doesn’t). By the way, ReSharper seems to have this feature.
The reason that the second line compiles is that there may be another class that derives from A and implements IC.
Classes can only inherit from one class, so you can never create a class that inherits from both A and B unless A is a descendent of B or vice-versa.