Выбрать главу

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

• классы S и T должны быть ссылочного типа;

• размерности массивов должны совпадать;

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

Заметьте, если S — это родительский класс, а T — его потомок, то для массивов одной размерности остальные условия выполняются. Вернемся теперь к примеру с классами 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 = ("Т. Xoap", "H. Вирт", "Э. Дейкстра"};

     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# более интересны. Надеюсь, с этим согласятся и читатели.

… В исходнике 13 лекция пропущена

14. Строки С#. Классы String и StringBuilder

Строки С#. Класс String. Изменяемые и неизменяемые строковые классы. Классы Net Framework, расширяющие строковый тип. Класс StringBuilder.

Класс String

В предыдущей лекции мы говорили о символьном типе char и строках постоянной длины, задаваемых массивом символов. Основным типом при работе со строками является тип string, задающий строки переменной длины. Класс String в языке C# относится к ссылочным типам. Над строками — объектами этого класса — определен широкий набор операций, соответствующий современному представлению о том, как должен быть устроен строковый тип.

Объявление строк. Конструкторы класса string

Объекты класса String объявляются как все прочие объекты простых типов — с явной или отложенной инициализацией, с явным или неявным вызовом конструктора класса. Чаще всего, при объявлении строковой переменной конструктор явно не вызывается, а инициализация задается строковой константой. Но у класса Sring достаточно много конструкторов. Они позволяют сконструировать строку из:

• символа, повторенного заданное число раз;

• массива символов char[];

• части массива символов.

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

public void TestDeclStrings()