- •11 Наследование
- •11.1 Основы наследования
- •11.2 Доступ к членам класса и наследование
- •11.2.1 Организация защищенного доступа
- •11.3 Конструкторы и наследование
- •11.3.1 Вызов конструкторов базового класса
- •11.4 Наследование и сокрытие имен
- •11.4.1 Применение ключевого слова base для доступа к скрытому
- •11.5 Создание многоуровневой иерархии классов
- •11.6 Порядок вызова конструкторов
- •11.7 Ссылки на базовый класс и объекты производных классов
- •11.8 Виртуальные методы и их переопределение
- •11.8.1 Что дает переопределение методов
- •11.8.2 Применение виртуальных методов
- •11.9 Применение абстрактных классов
- •11.10 Предотвращение наследования с помощью ключевого
- •11.11 Класс object
- •11.11.1 Упаковка и распаковка
- •11.11.2 Класс object как универсальный тип данных
11.11.2 Класс object как универсальный тип данных
Если object является базовым классом для всех остальных типов и упаковка значений простых типов происходит автоматически, то класс object можно вполне использовать в качестве "универсального" типа данных. Для примера рассмотрим программу, в которой сначала создается массив типа object, элементам которого затем присваиваются значения различных типов данных.
Листинг 11.28
// Использовать класс object для создания массива "обобщенного" типа.
using System;
class GenericDemo
{
static void Main()
{
object[] ga = new object[10];
// Сохранить целые значения.
for(int i=0; i < 3; i++)
ga[i] = i;
// Сохранить значения типа double.
for(int i=3; i < 6; i++)
ga[i] = (double) i / 2;
// Сохранить две строки, а также значения типов bool и char.
ga[6] = "Hello";
ga[7] = true;
ga[8] = 'X';
ga[9] = "Конец";
for(int i = 0; i < ga.Length; i++)
Console.WriteLine("ga[" + i + "]: " + ga[i] + " ");
}
}
Выполнение этой программы приводит к следующему результату.
ga[0]: 0
ga[1]: 1
ga[2]: 2
ga[3]: 1.5
ga[4]: 2
ga[5]: 2.5
ga[6]: Привет
ga[7]: True
ga[8]: X
ga[9]: Конец
Как показывает данный пример, по ссылке на объект класса object можно обращаться к данным любого типа, поскольку в переменной ссылочного типа object допускается хранить ссылку на данные всех остальных типов. Следовательно, в массиве типа object из рассматриваемого здесь примера можно сохранить данные практически любого типа. В развитие этой идеи можно было бы, например, без особого труда создать класс стека со ссылками на объекты класса object. Это позволило бы хранить в стеке данные любого типа.
Несмотря на то что универсальный характер класса object может быть довольно эффективно использован в некоторых ситуациях, было бы ошибкой думать, что с помощью этого класса стоит пытаться обойти строго соблюдаемый в С# контроль типов. Вообще говоря, целое значение следует хранить в переменной типа int, строку в переменной ссылочного типа string и т.д.
А самое главное, что начиная с версии 2.0 для программирования на С# стали доступными подлинно обобщенные типы данных обобщения (более подробно они будут рассматриваться позже). Внедрение обобщений позволило без труда определять классы и алгоритмы, автоматически обрабатывающие данные разных типов, соблюдая типовую безопасность. Благодаря обобщениям отпала необходимость пользоваться классом object как универсальным типом данных при создании нового кода. Универсальный характер этого класса лучше теперь оставить для применения в особых случаях.
