Почему интерфейсы в типах ссылок .Net?

Почему используются ссылочные типы интерфейсов? Насколько я понимаю, интерфейс - это контракт между классами (или структурами), так почему же это тип вообще? Я бы подумал, что это не тип значения или ссылочный тип.

Ответ 1

Чтобы обрабатываться как структура, компилятор должен знать во время компиляции, что такое конкретный тип, чтобы зарезервировать нужное пространство в стеке. Это означает, что , даже если структура реализует IFoo, а затем:

var ms = new MyStruct();
IFoo foo = ms;

тогда назначение foo является операцией бокса. Вы могли бы сказать, что "компилятор должен заметить, что он только когда-либо работает и использует" постоянный "код операции", но в общем случае (с несколькими присваиваниями foo и т.д.) Это невозможно (я бы рискнул предположить что он столкнется с проблемой "остановки" ).

Существует также проблема виртуального vs статического вызова, но "ограниченный" код операции работает вокруг этого.

В принципе, любое использование интерфейса всегда должно рассматриваться как ссылка.

Есть одно исключение: общие ограничения.

Если у вас

static void DoBar<T>(T target) where T : IFoo {
    target.Bar();
}

здесь метод JIT-1 раз для типа значения, поэтому пространство стека, необходимое для T , известно; вызов Bar является "ограниченным" и может быть виртуальным или статическим автоматически по мере необходимости.

Ответ 2

Они являются ссылочными типами, потому что типы значений имеют фиксированный размер во время компиляции, так что они могут быть выделены в стеке. Типы ссылок - указатели, поэтому указатели имеют постоянный размер, но они могут указывать на память любого размера.