public static void PrintObj (object A)
{
Console.WriteLine("A.GetType()={0})", A.GetType());
if (A.GetType()==typeof(System.Int32[]))
{
int[] temp;
temp = (int[])A;
for(int i = 0; i<temp.GetLength(0);i++)
Console.Write("\t temp[{0}]={1}", i,temp[i]);
Console.WriteLine ();
}
else
Console.WriteLine("Аргумент не является массивом целых");
}//PrintObject
Несколько замечаний к реализации.
Метод GetType, примененный к аргументу, возвращает не тип Object, а реальный тип фактического аргумента. Поэтому можно проанализировать, какому классу принадлежит объект, переданный в процедуру.
На каждой ветви разбора можно создать временный объект нужного типа и скопировать в него переданный аргумент. В данном примере рассматривается только одна ветвь, в которой создается целочисленный одномерный массив temp.
Заметьте, при присваивании значения переменной temp выполняется явное преобразование из класса Object в класс int[].
При наличии переменной temp, выполнение нужных действий над массивом не представляет никаких трудностей.
Приведу два примера вызова этой процедуры:
//работа с процедурой PrintObject
//Корректный и некорректный вызовы
Arrs.PrintObj (col1);
Arrs.PrintObj (соl3);
Вот какой вывод порождается этим фрагментом кода:
Рис. 12.4. Результаты работы процедуры PrintObj
Массивы объектов
Во всех рассмотренных примерах этой главы нам встречались массивы, элементы которых имели только простые значимые типы. В реальных программах массивы объектов и других ссылочных типов встречаются не менее часто. Каков бы ни был тип элементов, большой разницы при работе с массивами нет. Но один важный нюанс все же есть, и его стоит отметить. Он связан с инициализацией элементов по умолчанию. Уже говорилось о том, что компилятор не следит за инициализацией элементов массива и доверяет инициализации, выполненной конструктором массива по умолчанию. Но для массивов ссылочного типа инициализация по умолчанию присваивает ссылкам значение Null. Это означает, что создаются только ссылки, но не сами объекты. По этой причине, пока не будет проведена настоящая инициализация с созданием объектов и заданием ссылок на конкретные объекты, работать с массивом ссылочного типа будет невозможно.
Рассмотрим детали этой проблемы на примере. Определим достаточно простой и интуитивно понятный класс, названный Winners, свойства которого задают имя победителя и его премию, а методы позволяют установить размер премии для каждого победителя и распечатать его свойства. Приведу код, описывающий этот класс:
/// <summary>
/// Класс победителей с именем и премией
/// </summary>
public class Winners
{
//поля класса
string name;
int price;
//статическое или динамическое поле rnd?
//static Random rnd = new Random();
Random rnd = new Random();
// динамические методы
public void SetVals(string name)
{
this.name = name;
this.price = rnd.Next(5,10)* 1000;
}//SetVals
public void PrintWinner(Winners win)
{
Console.WriteLine("Имя победителя: {0}," +
" его премия — {1}", win.name, win.price);
}//PrintWinner
}//class Winners
Коротко прокомментирую этот текст.
1. Свойство name описывает имя победителя, а свойство price — величину его премии.
2. Свойство rnd необходимо при работе со случайными числами.
3. Метод SetVals выполняет инициализацию. Он присваивает полю name значение, переданное в качестве аргумента, и полю price — случайное значение.
4. Метод PrintWinner — метод печати свойств класса. Без подобного метода не обходится ни один класс.
5. В классе появится еще один статический метод InitAr, но о нем скажу чуть позже.
Пусть теперь в одном из методов нашего тестирующего класса Testing предполагается работа с классом Winners, начинающаяся с описания победителей. Естественно, задается массив, элементы которого имеют тип winners. Приведу начало тестирующего метода, в котором дано соответствующее объявление: