Чтобы считаться структурой, компилятор должен знать во время компиляции , что представляет собой конкретный тип, чтобы зарезервировать правильное пространство в стеке. Это означает, что , даже если структура реализует IFoo
, тогда с:
var ms = new MyStruct();
IFoo foo = ms;
, тогда присвоение foo
является операцией бокса. Вы могли бы сказать, что «компилятор должен заметить, что это только foo и использовать« заключенный »код операции», но в общем случае (с множественными присвоениями foo
и т.д.) это невозможно (Я бы рискнул предположить, что это решит проблему остановки).
Существует также проблема виртуального или статического вызова, но «ограниченный» код операции работает вокруг этого.
По сути, любое использование интерфейса всегда должно рассматриваться как ссылка.
Существует одно исключение: общие ограничения.
Если у вас есть
static void DoBar<T>(T target) where T : IFoo {
target.Bar();
}
здесь метод JITted один раз для каждого типа значения, поэтому пространство стека, необходимое для T
, известно как ; вызов Bar
является «ограниченным» и может быть виртуальным или статическим автоматически при необходимости.