netlib.narod.ru< Назад | Оглавление | Далее >

Генерация исключений

В программе работы с датами CsDateClass меня беспокоит то, что мы не добрались до истинной причины проблем. Метод DayOfYear генерирует исключение из-за того, что индекс массива MonthDays находится вне границ. Но настоящая проблема возникает в программе раньше и связана с инструкцией, которую я предложил добавить в программу:

  mydate.month = 13;

Сразу после его выполнения мы имеем дело с объектом Date, содержащим неправильную дату. В этом и заключается настоящая проблема. Просто получилось так, что DayOfYear оказался первым методом, который отрицательно реагирует на эту проблему. Но допустим, что вы введете в программу другую инструкцию:

  mydate.day = 47;

Метод DayOfYear выполнится без сообщений об ошибках и посчитает результат, несмотря на некорректность даты.

Есть ли способ встроить в класс защиту от присваивания полям некорректных значений программой, использующей этот класс? Проще всего описать поля как private, а не public.

  private int year;
  private int month;
  private int day;

Модификатор private делает эти три поля доступными только методам, находящимся внутри определения класса Date. На самом деле в С# атрибут private используется по умолчанию, так что для внесения этих изменений достаточно просто удалить атрибут public.

  int year;
  int month;
  int day;

Конечно, такое изменение порождает уже другую проблему. Как программа, использующая класс Date, должна устанавливать значения года, месяца и дня?

Одно из решений, которые могут прийти в голову, — определить методы класса Date, предназначенные специально для присваивания значений этих трех полей и для получения ранее присвоенных значений полей. Вот, например, два простых метода для присваивания и получения значения закрытого поля month:

  public void SetMonth (int month)
  {
      this.month = month;
  }
  public int GetMonth ()
  {
      return month;
  }

Заметьте: оба метода определены как public. Кроме того, я дал параметру метода SetMonth имя, совпадающее с именем поля! При этом перед именем поля нужно указывать слово this и точку. Внутри класса ключевое слово this означает тот экземпляр класса, чей метод был вызван. В статических методах ключевое слово this не допускается.

Вот версия SetMonth, проверяющая правильность значения месяца:

  public void SetMonth (int month)
  {
      if (month >= 1 && month <= 12)
          this.month = month;
      else
          throw new ArgumentOutOfRangeException("Month");
  }

В этом примере показан синтаксис генерации исключения. Я выбрал исключение ArgumentOutOfRangeException, так как оно наиболее адекватно идентифицирует проблему. Ключевое слово new используется для создания нового объекта типа ArgumentOutOfRangeException. Этот объект — то, что блок catch получает в качестве параметра. Параметром ArgumentOutOfRangeException является текстовая строка, идентифицирующая вызвавший проблему параметр. При выводе сообщения об исключении эта строка показывается вместе с другой информацией об ошибке.

В С# имеется достойная альтернатива методам Get и Set, Когда вы собираетесь писать методы, начинающиеся со слов Get и Set, более того, когда вы собираетесь писать любой метод, возвращающий информацию об объекте и не требующий параметров, вам следует подумать о такой возможности С#, как свойство (property).


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz