Недавно я был удивлен, обнаружив, что компилятор, по-видимому, не является строгим в сравнении ссылок на интерфейс, и мне интересно, почему он работает таким образом.
Рассмотрим этот код:
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
и не проблема.
Являются ли интерфейсы не объектами? Являются ли они особым типом ссылок? Мое ожидание было бы в том, что ==
приведет либо к прямому сравнению сравнения, либо к вызову в конкретный класс виртуальных равных.
Что мне не хватает?