Тверской государственный университет
Опубликован: 22.11.2005 | Доступ: свободный | Студентов: 30274 / 1763 | Оценка: 4.31 / 3.69 | Длительность: 28:26:00
ISBN: 978-5-9556-0050-5
Лекция 12:

Класс Array и новые возможности массивов

Массивы. Семантика присваивания

Преобразования между классами массивов и родительскими классами Array и Object уже рассматривались. А существуют ли другие преобразования между классами массивов? Что происходит при присваивании x=e ; (передаче аргументов в процедуру), если x и e - это массивы разных классов? Возможно ли присваивание? Ответ на этот вопрос положительный, хотя накладываются довольно жесткие ограничения на условия, когда такие преобразования допустимы. Известно, например, что между классами Int и Object существуют взаимные преобразования - в одну сторону явное, в другую неявное. А вот между классами Int[] и Object[] нет ни явных, ни неявных преобразований. С другой стороны, такое преобразование существует между классами String[] и Object[]. В чем же тут дело, и где логика? Запомните, главное ограничение на возможность таких преобразований состоит в том, что элементы массивов должны иметь ссылочный тип. А теперь притянем сюда логику. Крайне желательно обеспечить возможность проведения преобразований между массивами, элементы которых принадлежат одному семейству классов, связанных отношением наследования. Такая возможность и была реализована. А вот для массивов с элементами значимых типов подобную же возможность не захотели или не смогли реализовать.

Сформулируем теперь точные правила, справедливые для присваивания и передачи аргументов в процедуру. Для того, чтобы было возможным неявное преобразование массива с элементами класса S в массив с элементами класса T, необходимо выполнение следующих условий:

  • классы S и T должны быть ссылочного типа;
  • размерности массивов должны совпадать;
  • должно существовать неявное преобразование элементов класса S в элементы класса T.

Заметьте, если T - это родительский класс, а S - его потомок, то для массивов одной размерности остальные условия выполняются. Вернемся теперь к примеру с классами Int[], String[] и Object[]. Класс Int не относится к ссылочным классам, и потому преобразования класса Int[] в Object[] не существует. Класс string является ссылочным классом и потомком класса Object, а потому существует неявное преобразование между классами String[] и Object[].

Правило для явного преобразования можно сформулировать, например, так. Если существует неявное преобразование массива с элементами класса S в массив с элементами класса T, то существует явное преобразование массива с элементами класса T в массив с элементами класса S.

Для демонстрации преобразований между массивами написана еще одна процедура печати. Вот ее текст:

public static void PrintArObj(string name,object[] A)
{
	Console.WriteLine(name);
	foreach (object item in A )
		Console.Write("\t {0}", item);
	Console.WriteLine();
}//PrintArObj

Как видите, формальный аргумент этой процедуры принадлежит классу Object[]. При ее вызове фактическими аргументами могут быть массивы, удовлетворяющие выше указанным условиям. Вот пример кода, в котором вызывается эта процедура. В этом же фрагменте показаны и присваивания массива одного класса другому, где выполняются явные и неявные преобразования массивов.

public void TestMas()
{
	string[] winames = {"Т. Хоар", "Н. Вирт", "Э. Дейкстра"};
	Arrs.PrintArObj("winames", winames);
	object[] cur = new object[5];
	cur = winames;
	Arrs.PrintArObj("cur", cur);
	winames = (string[])cur;
	Arrs.PrintArObj("winames", winames);
}//TestMas

Взгляните на результаты работы этой процедуры.

Семантика присваивания и преобразования массивов

Рис. 12.6. Семантика присваивания и преобразования массивов

Приступая к описаниям массивов, я полагал, что 10 страниц одной лекции будет вполне достаточно. Оказалось, что массивы C# более интересны. Надеюсь, с этим согласятся и читатели.

Александр Галабудник
Александр Галабудник

Не обнаружил проекты, которые используются в примерах в лекции, также не увидел список задач.

Александра Гусева
Александра Гусева