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 | < Назад | Оглавление | Далее > |