Принципы объектно-ориентированного программирования

         

Упаковка и распаковка



Упаковка и распаковка

Как же эти различные категории типов обеспечивают более эффективную работу системы? Это делается с помощью упаковки (boxing). В простейшем случае при упаковке размерный тип преобразуется в ссылочный. В обратном случае ссылочный тип распаковывается (unbox) в размерный.

Замечательно в данной методике то, что объект лишь тогда является объектом, когда это необходимо. Допустим, вы объявляете переменную типа System.Int32. Для нее выделяется память в стеке. Вы можете передавать эту переменную любому методу, определенному в качестве принимающего аргументы типа System.Object, а также обращаться к любому из ее членов, к которому у вас есть доступ. Поэтому вы воспринимаете и ощущаете ее как объект. Но в реальности это всего 4 байта в стеке.



Только когда вы пытаетесь использовать эту переменную согласно правилам, определенным интерфейсом базового класса System.Object, система автоматически упаковывает переменную, в результате чего она становится ссылочным типом и может быть использована так же, как любой объект. Упаковка — это механизм, посредством которого в С# любая сущность может быть представлена в виде объекта. Это позволяет избежать издержек, неизбежных в том случае, если б всякая сущность на самом деле была объектом. Обратимся к примерам:

int foo = 42; // Размерный тип.

object bar = foo; // Переменная foo упакована в bar.

В первой строке этого кода мы создавали переменную (foo) типа int. Как вам известно, int является размерным типом (поскольку это базисный тип). Во второй строке компилятор обнаружит, что переменная foo скопирована в ссылочный тип, представленный переменной bar. При этом компилятор добавит код MSIL, необходимый для упаковки этой переменной.

А теперь выполним явное приведение типов, чтобы преобразовать bar обратно в размерный тип:

int foo = 42; // Размерный тип.

object bar = foo; // Переменная foo упакована в bar.

int foo2 = (int)bar; // Распаковка и приведение к типу int.

При упаковке (т. е. преобразовании из размерного типа в ссылочный) явного приведения типов не требуется. Однако при распаковке — преобразовании из ссылочного типа в размерный — приведение типов необходимо. Это так, потому что в случае распаковки объект может быть приведен к любому типу. Преобразование позволяет компилятору проверить, возможно ли приведение для заданного типа переменной. Поскольку приведение типов подчинено строгим правилам, определяемым CTS, мы рассмотрим этот случай подробнее в разделе «Приведение типов».

 

Содержание раздела