Разработка приложений на языке C#. Полезные настройки. Особые спецификаторы формата, страница 31

}

Отличием от С++ является способ вызова родительских версий унаследованных функций, для этого следует использовать ключевое слово base. Имя базового класса должен вычислить сам компилятор. Такое решение повышает надежность. Этот прием можно применять и при объявлении конструкторов, например

public Stud() : base() { course = 0; }

Метод вывода (Out) данных класса Man уже осуществляется с помощью переопределенной (override) виртуальной функции ToString, которую, как вы помните, получает в наследство любой класс. Вы помните имя неявного родителя всех классов? Если забыли, то это—System.Object. Именно в нем впервые определена функция: public virtual string ToString(); В производном классе (например, Man) она переопределена так, как показано ниже.

public override string ToString()  // Разделители понадобятся при чтении данных из файла

{

return name.PadRight (maxName) + " ; Age: " + age;

}

Декорации (символы ; и :) понадобятся при чтении (parsing'е) данных из файла. Вывод в файл произведем с помощью того же самого метода ToString. В класе Stud следует продолжить модификацию виртуального метода:

public override string ToString()

{

  return Class() + base.ToString() + ";  Course: " + course;

}

Добавим в класс Man метод общего характера: редактирование данных. Он может иметь сигнатуру:

  public void Edit()

  {

    Console.WriteLine (this);

    In ();

  }

Добавим еще один метод общего характера: чтение данных из файла. Он может иметь сигнатуру:

public virtual void Read (string[] tokens)

Разбить текстовую строку можно с помощью неподражаемого метода Split класса string. Он возвращает массив отдельных лексем (tokens), используя на входе массив разделителей (в нашем случае это ; и :). Важно лишь правильно выбрать индекс нужной лексемы. Массив разделителей создается по ходу дела. Например:

string[] tokens = line.Split ( new char[] {':',';'});

Этот прием весьма характерен для .NET. Мы воспользуемся им позже (в методе чтения данных из файла класса List), а сейчас продолжим анализ методов классов Man, Stud и Prof.

Симметричную функцию записи данных в файл (Write) вводить нет смысла. Нас опять выручит уже существующая виртуальная функция ToString. Она автоматически вызовется при выводе любого объекта из иерархии Man в файл (поток, поддерживаемый  классом StreamWriter) и корректно обслужит всех детей класса Man (объясните почему). Для иллюстрации нового для нас понятия delegate нам понадобятся еще два метода класса Man:

·  public void Surname() — вывод в консольное окно последнего слова из текстовой строки поля name,

·  public void Firstname() — вывод в консольное окно первого слова из строки поля name,

public void Surname() // Ищем последний пробел, считая, что фамилия расположена после него

{

      Console.WriteLine("  {0}", name.Substring (name.LastIndexOf(' ') + 1));

}

public void Firstname(){//===== Найдите первый пробел, считая, что Firstname расположено до него }

В области файловых операций библиотека .Net Framework Classes имеет много новых, приятных деталей, но для того, чтобы получить единый формат файлов с данными о людях, надо иметь более или менее единый подход к их реализации. Рекомендую подстроиться под такой формат файла данных списка людей.

MySoft, Man List v. 1.0

Stud: Alex Black     ; Age: 20;  Course: 3

Prof: Peter Pen      ; Age: 40;  Publications: 100

Первая строка позволяет отличить наш файл от всех других файлов типа .txt. Далее следует пустая строка. Ее надо учесть при чтении (такие вещи надо уметь делать). Вы можете использовать любой другой формат, даже XML, но тогда самостоятельно доведите дело до конца. Практика показывает, что далеко не все успешно справляются с файловыми операциями — они требуют особой аккуратности, поэтому приведу еще один метод класса Man. Он использует специфику выбранного формата данных.

public virtual void Read (string[] tokens) // Выбор данных из уже разобранной строки (массива лексем)

{