Почему используются ссылочные типы интерфейсов? Насколько я понимаю, интерфейс - это контракт между классами (или структурами), так почему же это тип вообще? Я бы подумал, что это не тип значения или ссылочный тип.
Почему интерфейсы в типах ссылок .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
Они являются ссылочными типами, потому что типы значений имеют фиксированный размер во время компиляции, так что они могут быть выделены в стеке. Типы ссылок - указатели, поэтому указатели имеют постоянный размер, но они могут указывать на память любого размера.