Недавно я с удивлением обнаружил, что компилятор явно не строг в сравнении ссылок на интерфейсы, и мне интересно, почему он работает таким образом.
Рассмотрим этот код:
class Program
{
interface I1 {}
interface I2 {}
class C1 : I1 {}
class C2 : I2 {}
static void Main(string[] args)
{
C1 c1 = new C1();
C2 c2 = new C2();
I1 i1 = c1;
I2 i2 = c2;
bool x = c1 == c2;
bool y = i1 == i2;
}
}
Компиляторговорит, что я не могу сравнить c1 == c2
, что следует.Типы абсолютно не связаны.Тем не менее, это позволяет мне сравнивать i1 == i2
.Я ожидал бы, что здесь произойдет ошибка с ошибкой во время компиляции, но я был удивлен, обнаружив, что вы можете сравнить любой интерфейс с любым другим, и компилятор никогда не будет жаловаться.Я мог бы сравнить, например, (I1)null == (IDisposable)null
и без проблем.
Разве интерфейсы не являются объектами?Это особый тип ссылки?Я ожидал бы, что ==
приведет либо к прямому эталонному сравнению, либо к вызову виртуального равенства Equals конкретного класса.
Чего мне не хватает?