Тип значения причины не может поддерживать наследование из-за массивов.
Проблема заключается в том, что по соображениям производительности и сборщика мусора массивы типов значений хранятся "встроенными". Например, если new FooType[10] {...}
, если FooType
является ссылочным типом, в управляемой куче будет создано 11 объектов (один для массива и 10 для каждого экземпляра типа). Если вместо FooType
указан тип значения, в управляемой куче будет создан только один экземпляр - для самого массива (так как каждое значение массива будет храниться «в ряд» с массивом).
Теперь предположим, что у нас было наследование с типами значений. В сочетании с описанным выше поведением массивов «встроенного хранилища», происходят плохие вещи, как можно видеть в C ++ .
Рассмотрим этот псевдо-C # код:
struct Base
{
public int A;
}
struct Derived : Base
{
public int B;
}
void Square(Base[] values)
{
for (int i = 0; i < values.Length; ++i)
values [i].A *= 2;
}
Derived[] v = new Derived[2];
Square (v);
По обычным правилам преобразования, Derived[]
конвертируется в Base[]
(к лучшему или к худшему), поэтому, если вы используете s / struct / class / g для приведенного выше примера, он будет скомпилирован и запущен, как ожидается без проблем. Но если Base
и Derived
являются типами значений, а массивы хранят значения встроенными, у нас возникает проблема.
У нас есть проблема, потому что Square()
ничего не знает о Derived
, он будет использовать только арифметику указателей для доступа к каждому элементу массива, увеличивая его на постоянную величину (sizeof(A)
). Сборка будет примерно такой:
for (int i = 0; i < values.Length; ++i)
{
A* value = (A*) (((char*) values) + i * sizeof(A));
value->A *= 2;
}
(Да, это отвратительная сборка, но дело в том, что мы будем увеличивать массив с известными константами времени компиляции, не зная, что используется производный тип.)
Итак, если бы это действительно произошло, у нас были бы проблемы с повреждением памяти. В частности, в пределах Square()
, values[1].A*=2
будет на самом деле изменяться values[0].B
!
Попробуйте отладить ТО !