ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
Шрифт:
Чтобы завершить обсуждение данной темы, изучите информацию табл. 3.8, в которой приводится краткая сводка основных отличий между типами, характеризуемыми значением, и ссылочными типами.
Таблица 3.8. Сравнение типов, характеризуемых значением, и ссылочных типов
Вопрос | Тип, характеризуемый значением | Ссылочный тип |
---|---|---|
Где размещается тип? | В стеке | В управляемой динамический памяти |
Как представляется переменная? | В виде локальной копии | В виде ссылки на место в памяти, занятое соответствующим экземпляром |
Что является базовым
| Оказывается производным от System.ValueType | Может получаться из любого типа, (кроме System.ValueType), не являющегося изолированным (подробности в главе 4) |
Может ли тип быть базовым для других типов? | Нет. Типы, характеризуемые значениями, всегда изолированы и не могут быть расширены | Да. Если тип не изолирован, он может быть базовым для других типов |
Каким является поведение, принятое по умолчанию при передаче параметров? | Переменные передаются по значению (т.е. вызванной функции передается копия переменной) | Переменные передаются по ссылке (например, в вызванную функцию передается адрес переменной) |
Может ли тип переопределить System.Object.Finalize? | Нет. Типы, характеризуемые значениями, никогда не размещаются в динамической памяти и поэтому не требуют финализации | Да, неявно (подробности в главе 4) |
Можно ли определить конструкторы для этого типа? | Да, но конструктор, заданный по умолчанию, является зарезервированным (т.е., другие конструкторы обязательно должны иметь аргументы) | Безусловно! |
Когда переменные данного типа прекращают свое существование? | Когда они оказываются вне контекста определения | Когда для управляемой динамической памяти выполняется сборка мусора |
Несмотря на указанные отличия, и типы, характеризуемые значением, и ссылочные типы могут реализовывать интерфейсы и поддерживать любое число полей, методов, перегруженных операций, констант, свойств и событий.
Операции создания объектного образа и восстановления из объектного образа
Ввиду того, что в .NET определяются две главные категории типов (характеризуемые значением или ссылкой), может понадобиться представление переменной одной категории в виде переменной другой категории. В C# предлагается очень простой механизм, называемый операцией создания объектного образа (boxing), позволяющий превратить тип, характеризуемый значением, в ссылочный тип. Предположим, что вы создали переменную типа short.
Если в приложении потребуется конвертировать этот тип значения в ссылочный тип, вы должны "упаковать" это значение так, как показано ниже.
Операцию создания объектного образа можно формально определить, как процесс явного преобразования типа, характеризуемого значением, в соответствующий ссылочный тип с помощью сохранения переменной в System.Object. Когда значение преобразуется в объектный тип, среда CLR размещает новый объект в динамической памяти и копирует значение соответствующего типа (в данном случае это значение 25) в созданный экземпляр. Вам возвращается ссылка на новый размещенный в памяти объект. При использований такого подхода у разработчика .NET не возникает необходимости использовать интерфейсные классы, чтобы временно обращаться с данными стека как с объектами, размещенными в динамической памяти.
Обратная операция тоже предусмотрена, и называется она восстановлением из объектного образа (unboxing). Восстановление из объектного образа является процессом обратного преобразования значения, содержащегося в объектной ссылке, в значение соответствующего типа, размещаемое в стеке. Операция восстановления из
Снова обратим ваше внимание на то, что восстановление следует выполнять в соответствующий тип данных. Так, следующая программная логика восстановления из объектного образа генерирует исключение InvalidCastException (обсуждение вопросов обработки исключений содержится в главе 6).
Примеры создания объектных образов и восстановления значений
Вы, наверное, спросите, когда действительно бывает необходимо вручную выполнять преобразование в объектный тип (или восстановление из объектного образа)? Предыдущий пример был исключительно иллюстративным, поскольку в нем для данных short не было никакой реальной необходимости приведении к объектному типу (с последующим восстановлением данных из объектного образа).
Реальность такова, что необходимость вручную приводить данные к объектному типу возникает очень редко – если возникает вообще. В большинстве случаев компилятор C# выполняет такие преобразования автоматически. Например, при передаче типа, характеризуемого значением, методу, предполагающему получение объектного параметра, автоматически "в фоновом режиме" происходит приведение к объектному типу.
Автоматическое преобразование в объектный тип происходит и при работе c типами библиотек базовых классов .NET. Например, пространство имен System.Collections (формально оно будет обсуждаться в главе 7) определяет тип класса с именем ArrayList. Подобно большинству других типов коллекций, ArrayList имеет члены, позволяющие вставлять, получать и удалять элементы.