- •Классы и структуры
- •Функции-члены
- •Передача параметров в методы
- •Параметры ref
- •Параметры out
- •Свойства
- •Свойства, доступные только для чтения и только для записи
- •Модификаторы доступа для свойств
- •Автоматически реализуемые свойства
- •Замечание о встраивании
- •Индексаторы
- •Тип_элемента this[int индекс]
- •Листинг 1.
- •Листинг 2.
- •Листинг 3.
- •Листинг 4.
- •Конструкторы
- •Статические конструкторы
- •Вызов одних конструкторов из других
- •Поля readonly
- •Анонимные типы
- •Структуры
- •Структуры это типы значений
- •Структуры и наследование
- •Конструкторы структур
- •Частичные классы
- •Статические классы
- •Класс Object
- •Методы System.Object
- •Метод ToString()
- •Расширяющие методы
Структуры это типы значений
Хотя структуры относятся к типам значений, очень часто их можно трактовать так же, как классы. Например, имея определение класса Dimensions из предыдущего раздела, можно написать следующий код:
Dimensions point = new Dimensions();
point.Length = 3;
point.Width = 6;
Следует обратить внимание, что поскольку структуры являются типами значений, операция new с ними работает несколько иначе, чем с классами и другими ссылочными типами. Вместо того чтобы выделять память в куче, операция new просто вызывает подходящий конструктор, инициализируя поля в соответствии с переданными ему параметрами. На самом деле, для структур можно написать такой код:
Dimensions point;
point.Length = 3;
point.Width = 6;
Если бы Dimensions был классом, это привело бы к ошибке компиляции, потому что point содержал бы неинициализированную ссылку т.е. адрес, ни на.что не указывающий, а потому вы не могли бы присваивать значения его полям. Для структур же объявление переменной на самом деле выделяет пространство в стеке для полной структуры, поэтому она тут же готова к присваиванию значений полям. Однако следует отметить, что показанный ниже код вызовет ошибку компиляции с сообщением о том, что используется неинициализированная переменная:
Dimensions point;
Double D = point.Length;
Структуры следуют тем же правилам, что и все другие типы данных: перед использованием все должно быть инициализировано. Структура рассматривается как полностью инициализированная, когда для ее создания была вызвана операция new или же когда всем ее полям индивидуально были присвоены значения. И, конечно же, структура, определенная как поле класса, инициализируется автоматическим обнулением при инициализации ее включающего объекта.
Тот факт, что структуры это типы значений, оказывает влияние на производительность. В зависимости от того, как используются структуры, это может быть и плохо, и хорошо. Положительным моментом является то, что выделение памяти для структур происходит очень быстро, потому что они встроены или размещаются в стеке. То же самое касается удаления структур при выходе из контекста. С другой стороны, всякий раз, когда вы передаете структуру в виде параметра или присваиваете одну структуру другой (как в А=В, когда А и В структуры), происходит копирование всего содержимого структуры, в то время как в случае с классами копируется только ссылка. Это приводит к потерям производительности, которые зависят от размера структуры это подчеркивает тот факт, что структуры на самом деле предназначены для хранения небольших порций данных. Тем не менее, когда структура передается методу в виде параметра, этих потерь производительности можно избежать, применяя ref-параметры при этом передается только адрес в памяти, где находится структура. Это так же быстро, как и передача объекта класса. С другой стороны, если вы так поступаете, то должны помнить, что вызываемый метод может в принципе изменить значение переданной структуры.
Структуры и наследование
Структуры не предназначены для наследования. То есть наследовать от структуры нельзя. Единственное исключение состоит в том, что структуры, как и все другие типы в С#, в конечном итоге наследуются от класса System.Object. Поэтому структуры имеют доступ к методам класса System.Object и даже могут переопределять их очевидным примером может служить переопределение метода ToString(). Действительная цепочка наследования, которая приводит к структуре, состоит в том, что каждая структура наследуется от класса System.ValueType, который, в свою очередь, наследуется от System.Object.ValueType, который не добавляет новых членов к Object, но предоставляет реализацию ряда из них более подходящим для структур способом. Следует отметить, что выбрать произвольный базовый класс для структуры невозможно: все они наследуются от ValueType.