Снова о создании объектных образов, восстановлении значений и System.Object

Снова о создании объектных образов, восстановлении значений и System.Object

Чтобы понять, в чем заключаются преимущества использования обобщений, следует выяснить, какие проблемы возникают у программиста без их использования. Вы должны помнить из главы 3, что платформа .NET поддерживает автоматическое преобразование объектов стека и динамической памяти с помощью операций создания объектного образа и восстановления из объектного образа. На первый взгляд, эта возможность кажется не слишком полезной и имеющей, скорее, теоретический, чем практический интерес. Но на самом деле возможность создания объектного образа и восстановления из объектного образа очень полезна тем, что она позволяет интерпретировать все, как System.Object, оставив все заботы о распределении памяти на усмотрение CLR.

Чтобы рассмотреть особенности процесса создания объектного образа, предположим, что мы создали System.Collections.ArrayList для хранения числовых (т.е. размещаемых в стеке) данных. Напомним, что все члены ArrayList обладают прототипами для получения и возвращения типов System.Object. Но вместо того, чтобы заставлять программиста вручную вкладывать размещенное в стеке целое число в соответствующую объектную оболочку, среда выполнения делает это автоматически с помощью операции создания объектного образа.

static void Main(string[] args) {

 // При передаче данных члену, требующему объект, для

 // характеризуемых значениями типов автоматически создается

 // объектный образ.

 ArrayList myInts = new ArrayList();

 myInts.Add(10);

 Console.ReadLine();

}

Чтобы восстановить значение из объекта ArrayList, используя индексатор типа, вы должны превратить размещенный в динамической памяти объект в размещенное в стеке целое число, используя операцию преобразования.

static void Main(string[] args) {

 …

 // Значение восстанавливается… и снова становится объектом!

 Console.WriteLine("Значение вашего int: {0}", (int)myInts[0]);

 Console.ReadLine();

}

Для представления операции создания объектного образа в терминах CIL компилятор C# использует блок box. Точно так же операция восстановления из объектного образа преобразуется в CIL-блок unbox. Вот соответствующий CIL-код для показанного выше метода Main() (этот код можно увидеть с помощью ildasm.exe).

.method private hidebysig static void Main(string[] args) cil managed {

 …

 box [mscorlib]System.Int32

 callvirt instance int32 [mscorlib] System.Collections.ArrayList::Add(object)

 pop

 ldstr "Значение вашего int: {0}"

 ldloc.0

 ldc.i4.0

 callvirt instance object [mscorlib] System.Collections.ArrayList::get_Item(int32)

 unbox [mscorlib]System.Int32

ldind.i4

 box [mscorlib]System.Int32

call void [mscorlib]System.Console::WriteLine(string, object)

 …

}

Обратите внимание на то. что перед обращением к ArrayList.Add() размещенное в стеке значение System.Int32 преобразуется в объект, чтобы передать требуемый System.Object. Также заметьте, что при чтении из ArrayList с помощью индексатора типа (что отображается в скрытый метод get_Item()) объект System.Object восстанавливается в System.Int32 только для того, чтобы снова стать объектным образом при передаче методу Console.WriteLine().

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Примеры создания объектных образов и восстановления значений

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Примеры создания объектных образов и восстановления значений Вы, наверное, спросите, когда действительно бывает необходимо вручную выполнять преобразование в объектный тип (или восстановление из объектного образа)? Предыдущий пример был исключительно иллюстративным,


Мастер-класс: System.Object

Из книги Win2K FAQ (v. 6.0) автора Шашков Алексей

Мастер-класс: System.Object Совет. Следующий обзор System.Object предполагает, что вы знакомы с понятиями виртуального метода и переопределения методов. Если мир ООП для вас является новым, вы можете вернуться к этому разделу после изучения материала главы 4.В .NET каждый тип в конечном


Переопределение элементов System.Object, заданных по умолчанию

Из книги Объектно-ориентированный анализ и проектирование с примерами приложений на С++ автора Буч Гради

Переопределение элементов System.Object, заданных по умолчанию Хотя заданное по умолчанию поведение System.Object может оказаться вполне приемлемым в большинстве случаев, вполне обычным для создаваемых вами типов будет переопределение некоторых из унаследованных методов. В главе


Переопределение System.Object.ToString()

Из книги Удвоение продаж в интернет-магазине автора Парабеллум Андрей Алексеевич

Переопределение System.Object.ToString() Переопределение метода ToString() дает возможность получить "снимок" текущего состояния объекта. Это может оказаться полезным в процессе отладки. Для примера давайте переопределим System.Object.ToString() так, чтобы возвращалось текстовое представление


Переопределение System.Object. Equals()

Из книги Цифровой журнал «Компьютерра» № 164 автора Журнал «Компьютерра»

Переопределение System.Object. Equals() Давайте переопределим и поведение System.Object.Equals(), чтобы иметь возможность работать с семантикой, основанной на значениях. Напомним, что по умолчанию Equals() возвращает true (истина), когда обе сравниваемые ссылки указывают на один и тот же объект в


Переопределение System.Object.GetHashCode()

Из книги автора

Переопределение System.Object.GetHashCode() Если класс переопределяет метод Equals(), следует переопределить и метод System.Object.GetHashCode(). Не сделав этого, вы получите предупреждение компилятора. Роль GetHashCode() – возвратить числовое значение, которое идентифицирует объект в зависимости от его


Статические члены System.Object

Из книги автора

Статические члены System.Object В завершение нашего обсуждения базового класса .NET, находящегося на вершине иерархии классов, следует отметить, что System.Object определяет два статических члена (Object.Equals() и Object.ReferenceEquals()), обеспечивающих проверку на равенство значений и ссылок


Переопределение System.Object.Finalize()

Из книги автора

Переопределение System.Object.Finalize() В тех редких случаях, когда воздается C#-класс, использующий неуправляемые ресурсы, нужно гарантировать, что соответствующая память будет обрабатываться прогнозируемым образом. Предположим, что вы создали класс MyResourceWrapper, использующий


Базовые классы System.MulticastDelegate и System.Delegate

Из книги автора

Базовые классы System.MulticastDelegate и System.Delegate Таким образом, при создании типов c помощью) ключевого слова delegate в C# вы неявно объявляете тип класса, являющегося производным от System.MulticastDelegate. Этот класс обеспечивает своим потомкам доступ к списку с адресами тех методов, которые


Проблемы создания объектных образов и восстановления значений

Из книги автора

Проблемы создания объектных образов и восстановления значений Операции создания объектных образов и восстановления из них значений очень удобны с точки зрении программиста, но такой упрощенный подход при обмене элементами стека и динамической памяти имеет свои


Проблемы создания объектных образов и строго типизованные коллекции

Из книги автора

Проблемы создания объектных образов и строго типизованные коллекции Строго типизованные коллекции можно найти в библиотеках базовых классов .NET и это очень полезные программные конструкции. Однако эти пользовательские контейнеры мало помотают в решении проблем


Получение Туре с помощью System.Object.GetType()

Из книги автора

Получение Туре с помощью System.Object.GetType() Экземпляр класса Туре можно получить множеством способов. Нельзя только непосредственно создать объект Туре, используя для этого ключевое слово new, поскольку класс Туре является абстрактным. Чтобы привести пример одной из


(8.11) После подключения дополнительного жесткого диска W2k перестал загружаться. После ввода пароля говорит, что "your system has no paging file, or the paging file is too small" и снова выдает окно логона. Что делать?

Из книги автора

(8.11) После подключения дополнительного жесткого диска W2k перестал загружаться. После ввода пароля говорит, что "your system has no paging file, or the paging file is too small" и снова выдает окно логона. Что делать? Данная проблема появляется, если буква загрузочного раздела не совпадает с буквой,


А.5. Common Lisp Object System (CLOS)

Из книги автора

А.5. Common Lisp Object System (CLOS) Происхождение Существуют буквально десятки диалектов языка Lisp, включая MacLisp, Standard Lisp, SpiceLisp, S-1 Lisp, ZetaLisp, Nil, InterLisp и Scheme. В начале 80-х годов под воздействием идей объектно-ориентированного программирования возникла серия новых диалектов Lisp, многие из


Глава 6. Клиенты, которые покупают снова и снова

Из книги автора

Глава 6. Клиенты, которые покупают снова и снова Начните вести клиентскую базу Большая часть прибыли интернет-магазинов строится на постоянных клиентах, которые совершают регулярные покупки. Однако часто покупатели не возвращаются лишь потому, что забыли про ваш


Ложь навсегда: почему нас обманывают снова и снова Василий Щепетнёв

Из книги автора

Ложь навсегда: почему нас обманывают снова и снова Василий Щепетнёв Опубликовано 17 марта 2013 На днях попалась мне книга с примечательным названием: «Как узнать, что вас опять обманывают». Стояла она на полке магазина не вольно, а запечатанная в