Типы интерфейса не наследуются от Object
, но места хранения типов интерфейса содержат ссылки на объекты типа класса, которые (если не ноль) гарантированно наследуют от System.Object
.
Я думаю, что понять, что происходит, будет проще, если начать с изучения различий между типами значений и типами классов. Предположим, у меня есть структура:
public struct SimplePoint {public int x,y;}
и у меня есть два метода
public doSomethingWithPoint(SimplePoint pt) ...
public doSomethingWithObject(Object it) ...
и вызывайте каждый метод:
SimplePoint myPoint = ...;
doSomethingWithPoint(myPoint);
dosomethingWithObject(myPoint);
Первый вызов не передает то, что происходит от Object
. Вместо этого он передает содержимое всех открытых и закрытых полей SimplePoint
. Второму вызову нужна вещь, которая происходит от Object
, поэтому он генерирует новый экземпляр объекта кучи типа SimplePoint
, который содержит все открытые и закрытые поля типа-значения SimplePoint
, и загружает все эти поля с помощью соответствующие значения из myPoint
и передает ссылку на этот объект.
Обратите внимание, что тип SimplePoint
на самом деле описывает два разных вида вещей: набор полей (то есть тип значения) и тип объекта кучи. Какое значение применимо, зависит от контекста, в котором используется тип.
Типы интерфейса имеют похожую складку: при использовании в качестве типов места хранения они указывают, что место хранения будет содержать ссылку на объект. При использовании в качестве общего ограничения они ничего не говорят о том, как будет храниться тип. Таким образом, место хранения типа интерфейса будет содержать ссылку на объект кучи, который действительно наследует от System.Object
, но переменная типа, ограниченного интерфейсом, может содержать либо ссылку, либо набор полей.