Разработка свойств
Примечание.
Это содержимое перепечатывается разрешением Pearson Education, Inc. из руководства по проектированию платформы: соглашения, идиомы и шаблоны для повторно используемых библиотек .NET, 2-го выпуска. Этот выпуск был опубликован в 2008 году, и книга с тех пор была полностью пересмотрена в третьем выпуске. Некоторые сведения на этой странице могут быть устаревшими.
Хотя свойства технически похожи на методы, они сильно отличаются в плане сценариев их использования. Они должны отображаться как интеллектуальные поля. Они имеют синтаксис вызова полей и гибкость методов.
✔️ СОЗДАВАЙТЕ свойства, отвечающие только за получение, если вызывающий объект не может изменить значение свойства.
Помните, что если тип свойства является изменяемым ссылочным типом, значение свойства можно изменить, даже если оно отвечает только за получение.
❌ НЕ предоставляйте свойства, отвечающие только за установку, или свойства с методом задания, который имеет более широкие возможности доступа, чем метод получения.
Например, не используйте свойства с открытым методом задания и защищенным методом получения.
Если невозможно предоставить метод получения свойства, реализуйте в качестве метода функцию. Начните имя метода с Set
, а затем добавьте имя свойства. Например, у элемента AppDomain есть метод с именем SetCachePath
, а не свойство CachePath
, доступное только для получения.
✔ ПРЕДОСТАВЬТЕ допустимые значения по умолчанию для всех свойств таким образом, чтобы значения по умолчанию не вызвали брешь в системе безопасности и не привели к появлению неэффективного кода.
✔️ РАЗРЕШИТЕ задавать свойства в любом порядке, даже если в результате этого может возникнуть временное недопустимое состояние объекта.
Обычно два или более свойств взаимосвязаны таким образом, что некоторые значения одного свойства могут оказаться недопустимыми при наличии значений других свойств того же объекта. В таких случаях исключения, являющиеся результатом недопустимого состояния, следует отложить до тех пор, пока взаимосвязанные свойства не будут фактически использованы объектом вместе.
✔️ СОХРАНИТЕ предыдущее значение, если метод задания свойства создает исключение.
❌ НЕ создавайте исключения из методов получения свойств.
Методы получения свойств должны быть простыми операциями и не иметь никаких предусловий. Если метод получения может вызвать исключение, его следует переделать в метод. Обратите внимание, что это правило не применяется к индексаторам, в которых мы ожидаем исключения в результате проверки аргументов.
Разработка индексируемых свойств
Индексируемое свойство — это специальное свойство, которое может иметь параметры и вызываться с помощью специального синтаксиса, аналогичного индексации массива.
Индексируемые свойства обычно называются индексаторами. Индексаторы следует использовать только в интерфейсах API, которые предоставляют доступ к элементам в логической коллекции. Например, строка представляет собой набор символов, а индексатор для System.String добавлен для доступа к его символам.
✔️ РАССМОТРИТЕ возможность использования индексаторов для обеспечения доступа к данным, хранящимся во внутреннем массиве.
✔️ РАССМОТРИТЕ возможность предоставления индексаторов для типов, представляющих коллекции элементов.
❌ НЕ используйте индексируемые свойства с несколькими параметрами.
Если для проектирования требуется несколько параметров, следует подумать, действительно ли свойство представляет метод доступа к логической коллекции. Если это не так, используйте методы. Начните имя метода с Get
или Set
.
❌ НЕ используйте индексаторы с типами параметров, отличными от System.Int32, System.Int64, System.String, System.Object или типа перечисления.
Если для разработки требуются другие типы параметров, повторно проанализируйте, действительно ли API представляет метод доступа к логической коллекции. В противном случае используйте метод. Начните имя метода с Get
или Set
.
✔️ ИСПОЛЬЗУЙТЕ имя Item
для индексируемых свойств, если нет явно лучшего имени (например, см. свойство Chars[] для System.String
).
В C# индексаторы по умолчанию имеют имя Item. Для настройки этого имени можно использовать IndexerNameAttribute.
❌ НЕ предоставляйте индексатор и методы, которые семантически эквивалентны.
❌ НЕ предоставляйте более одного семейства перегруженных индексаторов в одном типе.
Это реализуется компилятором C#.
❌ НЕ используйте нестандартные индексируемые свойства.
Это реализуется компилятором C#.
События уведомлений об изменении свойств
Иногда бывает полезно указать событие, уведомляющее пользователя об изменениях в значении свойства. Например, System.Windows.Forms.Control
вызывает событие TextChanged
после изменения значения свойства Text
.
✔️ РАССМОТРИТЕ возможность вызова событий уведомлений об изменениях при изменении значений свойств в интерфейсах API высокого уровня (обычно в компонентах конструктора).
Если есть подходящий сценарий, при котором пользователю известно, когда изменяется свойство объекта, объект должен создать событие уведомления об изменении для свойства.
Однако вряд ли стоит тратить ресурсы на создание таких событий для низкоуровневых API, таких как базовые типы или коллекции. Например, List<T> не будет вызывать такие события при добавлении нового элемента в список и изменении свойства Count
.
✔️ РАССМОТРИТЕ возможность создания событий уведомления об изменениях, когда значение свойства изменяется под действием внешних факторов.
Если значение свойства изменяется с помощью некоторых внешних факторов (не путем вызова методов объекта), вызываемые события указывают разработчику, что значение изменяется или изменилось. Хорошим примером является свойство Text
элемента управления текстовым полем. Когда пользователь вводит текст в TextBox
, значение свойства изменяется автоматически.
Фрагменты: © Корпорация Майкрософт (Microsoft Corporation), 2005, 2009. Все права защищены.
Перепечатано с разрешения Pearson Education, Inc. из книги Инфраструктура программных проектов. Соглашения, идиомы и шаблоны для многократно используемых библиотек .NET (2-е издание), авторы: Кржиштоф Цвалина (Krzysztof Cwalina) и Брэд Абрамс (Brad Abrams). Книга опубликована 22 октября 2008 г. издательством Addison-Wesley Professional в рамках серии, посвященной разработке для Microsoft Windows.