15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс

^ 15.4. Упаковка и распаковка
Когда значение структурного типа преобразуется к типу object либо приводится к типу того интерфейса, который реализован структурой, производится операция упаковки (boxing). Эта операция производится автоматом и не просит вмешательства программера.

Упаковкой именуют 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс процесс очевидного преобразования из типа значений в тип ссылок. При упаковке создаётся и располагается куче объект, которому присваивается значение объекта с типом значения. Возвращаемым значением при выполнении упаковки служит 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс ссылка на объект кучи.

Оборотной операцией является распаковка (unboxing), при которой значение объекта присваивается переменной с типом значения.

Автоматическая упаковка производится в тех случаях, когда производится допустимое присваивание ссылке на объект ссылочного 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс типа переменной с типом значения. Потому что все классы языка C# имеют общий базисный класс object , то ссылке типа object можно присвоить значение структуры. В данном случае производится автоматическая упаковка, не требующая вмешательства программера. Оборотная 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс процедура – распаковка – автоматом не производится. Для распаковки нужно использовать операцию приведения типов.

Произнесенное относится не только лишь к присваиванию, да и к передаче характеристик и к возвращаемому способом результату. Разглядим статический 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс способ с таким заголовком:

static object reDouble(object obj)

Способ воспринимает ссылку на объект типа object и возвращает значение такого же типа. Снаружи ничто не препятствует применению в воззвании к этому способу 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс в качестве аргумента ссылки на объект хоть какого типа. Но, в теле способа нужно учесть определенный тип аргумента, и сформировывать возвращаемый итог в согласовании с этим типом. В последующей программке определена структура 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс Struct1 с полем x типа double, и способ с приведенным выше заголовком.

// 15_10.cs - структуры, упаковка, распаковка

using System;

struct Struct1 // структура

{

double x;

public double X { get { return x; } set { x = value; } }

}

class Program

{

static 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс object reDouble(object obj)

{

if (obj is Struct1)

{

Struct1 st = (Struct1)obj;

st.X = 2 * st.X;

return st;

}

else

Console.WriteLine("Неведомый тип!");

return obj;

}

static void Main()

{

Struct1 one = new Struct 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс1();

one.X = 4;

Struct1 two = (Struct1)reDouble(one);

Console.WriteLine("one.X={0}; two.X={1}",

one.X, two.X);

Console.WriteLine("(int)reDouble(55)={0}",

(int)reDouble(55));

}

}


Итог выполнения программки:

one.X=4; two.X=8

Неведомый тип!

(int 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс)reDouble(55)=55


Способ reDouble() обрабатывает только аргументы типа Struct1, хотя ему можно передать аргумент хоть какого типа. Если аргумент имеет тип Struct1, способ reDouble() делает его распаковку и умножает значение поля double 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс x. Если тип аргумента отличен от Struct1, то тип распознаётся как неведомый и аргумент ворачивается в точку вызова в «упакованном» виде. Для примера в способе Main() воззвание к reDouble() выполнено два раза с 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс аргументами различных типов.

Осознание процедур упаковки и распаковки нужно для внедрения таких библиотечных средств как коллекции. К ним относится класс ArrayList (массив-список) из места имён System.Collections. Объект класса ArrayList 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс в почти всех случаях «ведёт себя» как массив. К примеру, к нему применима индексация. В отличие от массивов, производных от класса Array, объекты класса ArrayList могут расти в процессе выполнения программки. Количество 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс их частей возрастает, как в этом появляется необходимость, причём рост производится автоматом без вмешательства программера.

Но не всё просто. Разглядим объявление такового возрастающего массива-списка:

using System.Collection;

…..

ArrayList dinamo = new 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс ArrayList(3);


В данном примере объявлена ссылка dinamo и ассоциированный с нею объект класса ArrayList. В воззвании к конструктору ArrayList() указан исходный размер массива-списка. Можно представить, что сейчас можно обращаться к элементам массива-списка 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс, используя индексы со значениями 0, 1, 2. Но последующая попытка будет неверной:

dinamo [1]=45.3; // ошибка времени выполнения

Даже, если в вызове конструктора указан размер массива-списка, сначало частей в создаваемом массиве-списке НЕТ! Отличие объекта 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс класса ArrayList от обычного массива заключается в том, что в массив-список элементы должны быть сначала занесены при помощи нестатического способа Add() класса ArrayList.

Заголовок способа: public virtual int Add(object value)

Способ 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс добавляет в конец массива-списка элемент, данный аргументом. Возвращаемое значение – порядковый номер (индекс) добавленного элемента. Нумерация частей начинается с нуля.

Потому что тип параметра object, то в качестве аргумента можно использовать значение 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс хоть какого типа. Как следует, в один массив-список можно помещать элементы различных типов. Процедура упаковки, нужная для аргументов с типами значений, производится автоматом. А вот при получении значения элемента массива 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс-списка необходимо очевидно выполнить распаковку, узнав за ранее какой тип имеет элемент.

В последующей программке сотворен массив-список, представляемый ссылкой ArrayList dynamo. Потом в этот массив-список добавлены элементы со значениями double, int и 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс PointS, где PointS – пользовательский тип, объявленный в программке как структура. Текст программки:

// 15_11.cs - структуры и массив-список типа ArrayList

using System;

using System.Collections; // Для ArrayList

class Program

{

static void Main()

{

ArrayList dinamo = new ArrayList();

dinamo 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс.Add(4.8);

dinamo.Add(new PointS());

dinamo.Add(100);

PointS ps = new PointS();

ps.X = 10.2;

dinamo.Add(ps);

dinamo[1] = 1.23;

foreach (object ob in dinamo)

if (ob is PointS)

Console.WriteLine("Struct: X={0}; Y={1}",

((PointS 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс)ob).X, ((PointS)ob).Y);

else

if (ob is Double)

Console.WriteLine("Double: Value={0}",

((double)ob).ToString());

}

}

struct PointS // структура

{

double x, y;

public double X { get { return x; } set { x 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс = value; } }

public double Y { get { return y; } set { y = value; } }

}


Итог выполнения программки:

Double: Value=4,8

Double: Value=1,23

Struct: X=10,2; Y=0


В способе Main( ) после размещения в массиве-списке dinamo четырёх частей, эти 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс элементы перебираются в цикле foreach. Параметр цикла ob имеет тип object. Ему поочередно присваиваются ссылки на разнотипные элементы массива-списка. Конкретно использовать параметр типа object для доступа к объектам различных типов нереально – у каждого типа 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс своя структура, свои члены, свои поля. В теле цикла условные операторы, созданные для определения типов. Распознаются только типы double и PointS. В качестве проверяемого условия в операторах if употребляется выражение с 15.4. Упаковка и распаковка - В. В. Подбельский Язык C#. Базовый курс операцией is. Направьте внимание как при помощи выражения с индексацией выполнено присваивание второму элементу массива-списка:

dinamo[1] = 1.23;

Перед этим присваиванием значением элемента dinamo[1] был объект структуры PointS.



157-100-itogi-gak-trudoustrojstvo-i-vostrebovannost-vipusknikov-upravlenie-kachestvom-podgotovki-specialistov.html
158-analiz-riskov-realizacii-podprogrammi-i-opisanie-mer-upravleniya-riskami-realizacii-podprogrammi.html
158-stalin-molotovu-kaganovichu-voroshilovu-ordzhonikidze-s-2001-g-knigi-serii-vihodyat-na-russkom-yazike-v-izdatelstve.html