Введение - зачем используются структуры?
Все мы сильно любим структуры (идея, чуждая Java, не считая примитивных типов). Структуры, когда они не упакованы, зачастую, предоставляют прекрасную возможность обрабатывать динамические данные относительно небольшого размера.
Размещение и освобождение типов данных в целом проще, чем размещение и освобождение ссылочных типов. Это связано тем, что структуры размещаются в стеке, либо встроены в содержащиеся типы и освобождаются, при очищении стека либо когда встроенные типы перераспределяются, в то время, как ссылочные типы размещаются в куче и очищаются сборщиком мусора (garbage-collected)
Хм... Структуры не хотят наследоваться.
Объектно-Ориентированное Программирование дает нам возможность делать много полезных вещей. И основной коцепт - это, конечно же, наследование. Многие из нас, когда либо, пытались наследовать структуру только для того, что бы понять, что C# не позволит нам этого сделать.
Для примера рассмотрим код:
// Что может быть не так с этим простым кодом?
// DateTime это структура, если вы еще об этом не знаете, то Now() хорошее время для того, что // бы узнать это :)
struct MyDateTime : DateTime
{
double SecondsFromMyBirthday { get; private set; }
}
// или с этим, довольно разумным запросом на наследование:
struct Point
{
int x, y;
}
struct Point3D : Point
{
int z;
}
Честно говоря, каждый программист желает расширить структура DateTime, не так ли?
Это код выведет ошибку компиляции: Type 'DateTime' in interface list is not an interface.
Если структура будет перемещена в класс, то выйдет следующая ошибка компиляции: 'MyDateTime': cannot derive from sealed type 'System.DateTime'.
Теперь мы понимаем, что System.DateTime упакован. Но почему?
Замечание: фактически, все типы структур унаследованы от класса System.ValueType, который, в свою очередь унаследован от класса object.
Ответ
В памяти структуре выделен стек фиксированного размера.
Давайте рассмотрим код примера Point/Point3D структуры, который указан выше. Рассмотрим следующую строку кода:
// Предположительно, у нас есть p2d - Point,
// и p3d - Point3D
p2d = p3d;
Что должно произойти? Стек p2d расширит свою память для поддержки присвоения?
Кроме того, структуры, являясь типами значений, не используют ссылки (кроме упакованных). Это сделало бы полиморфизм бессмысленным, поскольку отсутствуют пути через ссылочные указатели.
Что же касается массивов, массивы типов данных хранятся "inline" (для повышения производительности и сборки мусора). Если мы будем использовать структуру без понимания этого, то "обрезанная структура" приведет к повреждению памяти.
В заключении - мы увидели неразумность наследования структур в .NET. Хорошая новость - наследовать можно классы.
Источник: http://www.codeproject.com/Tips/877525/Inherit-a-struct-in-Csharp-why-not
Комментарии
Отправить комментарий