Г. Шилдт - С#4.0 Полное руководство (1160795), страница 59
Текст из файла (страница 59)
В частности, свойство состоит из имени и аксессоров цес и вес. Аксессоры служат для получения и установки значения переменной. Главное преимущество свойства заключается в том, что его имя может быть использовано в выражениях и операторах присваивания аналогично имени обычной переменной, но в действительности при обращении к свойству по имени автоматически вызываются его аксессоры оес и яес. Аналогичным образом используются аксессоры сес и яег. индексатора. Ниже приведена общая форма свойства: тип имя( апет( код аксессора для чтения из поля ) яес( !) код аксессора для записи в поле ) где тип обозначает конкретный тип свойства, например 10 5, а имя — присваиваемое свойству имя.
Как только свойство будет определено, любое обращение к свойству по имени приведет к автоматическому вызову соответствующего аксессора. Кроме того, аксессор яес принимает неявный параметр ча1це, который содержит значение, присваиваемое свойству.
314 Часть ). Язык С№ Следует, однако, иметь в виду, что свойства не определяют место в памяти для хранения полей, а лишь управляют доступом к полям. Это означает, что само свойство не предоставляет поле, и поэтому поле должно быть определено независимо от свойства. (Исключение из этого правила составляет автоматически реализуемое свойство, рассматриваемое далее.) Ниже приведен простой пример программы, в которой определяется свойство Мургор, предназначенное для доступа к полю ргор. В данном примере свойство допускает присваивание только положительных значений. // Простой пример применения свойства. оя1пд Яуягещ; с1аяя Ягщрргор ( гпт ргор; // поле, управляемое свойством МуРгор рцЬ11с Ятщрргор() ( ргор = 0; ) /* Это свойство обеспечивает доступ к закрытой переменной экземпляра ргор.
Оно допускает присваивание только положительных значений. */ рпЬ11с 1пс МуРгор ( дег ( гегцгп ргор; ) яег ( РГ(ча1це >= 0) ргор = ча1це; ) // Продемонстрировать применение свойства. с1аяя Ргорегтуоещо ( ясасгс чогг( Маги() ( ЯтщрРгор оЬ = пен ЯгщрРгор(); Сопяо1е.иггтеэьпе("Первоначальное значение оЬ.Мургор: " + оЬ.Мургор) оЬ.Мургор = 100; // присвоить значение Сопяо1е.Игтсеэьпе("Текущее значение оЬ.Мургор: " + оЬ.Мургор) // Переменной ргор нельзя присвоить отрицательное значение. Сопяо1е.нггтеьгпе("Попытка присвоить значение "-10 свойству оЬ.Мургор")у оЬ.МуРгор = -10; Сопяо1е.иггсеьгпе('"Текущее значение оЬ.МуРгор: " + оЬ.МуРгор) ) ) Вот к какому результату приводит выполнение этого кода.
Первоначальное значение оЬ.МуРгор: 0 Текущее значение оЬ.Мургор: 100 Попытка присвоить значение -10 свойству оЬ.Мургор Текущее значение оЬ.Мургор: 100 Глава 10. 'г)ндексагоры и свойства 315 Рассмотрим приведенный выше код более подробно. В этом коде определяется одно закрытое поле ргор и свойство МуРгор, управляющее доступом к полю ргор. Как пояснялось выше, само свойство не определяет место в памяти для хранения поля, а только управляет доступом к полю. Кроме того, поле р гор является закрытым, а значит, оно доступно только через свойство Мур гор.
Свойство Мургор указано как рцЬ11с, а следовательно, оно доступно из кода за пределами его класса. И в этом есть своя логика, поскольку данное свойство обеспечивает доступ к полю ргор, которое является закрытым. Аксессор дег этого свойства просто возвращает значение из поля ргор, тогда как аксессор яег устанавливает значение в поле ргор в том и только в том случае, если это значение оказывается положительным. Таким образом, свойство Мургор контролирует значения, которые могут храниться в поле ргор.
В этом, собственно, и состоит основное назначение свойств. Тип свойства Мургор определяется как для чтения, так и для записи, поскольку оно позволяет читать и записывать данные в базовое поле. Тем не менее свойства можно создавать доступными только для чтения или только для записи. Так, если требуется создать свойство, доступное только для чтения, то достаточно определить единственный аксессор дег. А если нужно создать свойство, доступное только для записи, то достаточно определить единственный аксессор яеб. Воспользуемся свойством для дальнейшего усовершенствования отказоустойчивого массива.
Как вам должно быть уже известно, у всех массивов имеется соответствующее свойспю длины (ЬепдГЬ). До сих пор в классе Ра115оГГАггау для этой цели использовалось открытое целочисленное поле ЬепдГЬ. Но это далеко не самый лучший подход, поскольку он допускает установку значений, отличающихся от длины отказоустойчивого массива. (Например, программист, преследующий злонамеренные цели, может умышленно ввести неверное значение в данном поле.) Для того чтобы исправить это положение, превратим поле ЬепдГЬ в свойство "только для чтения", как показано в приведенном ниже, измененном варианте класса Ра11зог ГАггау. Добавить свойство ЬепдГЬ в класс Ра11зоГГАггау.
ця1пд Бувгеиг с1аяя Ра11зоГГАггау [ гпс[) аг // ссылка на базовый массив 1пс 1еп; // длина массива — служит основанием для свойства Ьепдсь рцЬ11с Ьоо1 КггР1адг // обозначает результат последней операции Построить массив заданного размера. рцЬ11с Га115оГГАггау[1пс яхте) [ а = пен гпг[ягяе); 1еп = ягяег ) // Свойство ЬепдГЬ только для чтения. рцЬ11с гпс Ьепдсб [ дег [ гесцгп 1епг ) 316 Часть 1. Язык С() // Это индексатор для класса Ра115отгкггау.
рцЬ11с гпс Гнья(ьпя Епбех) ( // Это аксессор сег. дег ( 1Е(ох(1пбех) ) ЕггР1ад = Еа1яе; геьцгп а(зпбех]( ) е1яе ( Еггу1ас = ггце; гегцгп 0; ) ) // Это аксессор яег. яег ( гЕ(ох(1пбех)) ( а (Елях) = ча1пет ЕггР1ас = Еа1яе; ) е1яе Еггр1ас = Ггце; // Возвратить логическое значение Сгце, если // индекс находится в установленных границах. ргьчаге Ьоо1 ох(1пг Епбех) ( 1Е(1пг)ех >= 0 а 1пг(ех < ьепсгь) гегцгп ггцет гегцгп Еа1яе) ) // продемонстрировать применение усовершенствованного // отказоустойчивого массива.
с1аяя 1щргочедРБРешо ( ягаг1с чотб Магп() ( Ра11$оЕСЯггау Ея = пен Ра11зотсйггау(5)т гпг х) // Разрешить чтение свойства Ьепоял. Еог(гпг г=с) г < Ея.Ьепдсьы 1а+) Ея(г) = 1*10т Еог(1пс г=с) г < Ея.ьепдсь; г+т) ( х = Ее[1); ЕЕ(х != -1) Сопяо1е.нг1се(х т " "); ) Сопяо1е.нггсеЬгпе(); // Ея.ьепдсь = 10; // Ошибка, запись запрещена! ) ) Теперь ьепдЬЬ вЂ” это свойство, в котором местом для хранения данных служит закрьпая переменная 1еп.
А поскольку в этом свойстве определен единственный ак- Глава 10. Индексаторы и свойства 317 сессор пес, то оно доступно только для чтения. Это означает, что значение свойства Ьеппбб можно только читать, но не изменять. Для того чтобы убедиться в этом, попробуйте удалить символы комментария в начале следующей строки из приведенного выше кода. // Ея.Ьепссб = 10; // Ошибка, запись запрещена! При попытке скомпилировать данный код вы получите сообщение об ошибке, уведомляющее о том, что Ьеп убп является свойством, доступным только длл чтения. Добавлением свойства Ьеппбп в класс Еа11Боббйггау усовершенствование рассматриваемого здесь примера кода с помощью свойств далеко не исчерпывается.
Еще одним членом данного класса, подходящим для превращения в свойство, служит переменная Еггр1ап, поскольку ее применение должно быть ограничено только чтением. Ниже приведен окончательно усовершенствованный вариант класса Еа11ЯОЕСАггау, в котором создается свойство Еггог, использующее в качестве места для хранения данных исходную переменную Е г гр1аоь СтавшуЮ теперь закрытой.
Превратить переменную ЕггР1ас в свойство. цяьпс Яуясещ; с1авя Еа11яоЕГАггау ( 1пс[) а; // ссылка на базовый массив ьпг 1еп; // длина массива Ьоо1 Еггр1аеы // теперь зто частная переменная, обозначающая результат последней операции О Построить массив заданного размера. роб11с Еа11Боуслггау(ьпг яьге) ( а = пен хпб[ягге!; 1еп = яьге; ) Свойство Ьепсяб только для чтения. рпЫ1с 1пп Ьепссб ( чег ( гегцгп 1еп; Свойство Еггог только для чтения. рцЫьс Ьоо1 Еггог ( пег. ( гегцгп Еггт1асы ) ) Это индексатор для класса Еат1зобслггау.
рпЫ1с ьпг гЫя[тпг ьпбех] ( // Это аксессор Пес. чег ( го(ок(1пбех)) ЕггЕ1ао = Еа1яеу гегцгп а[ьпбех); 318 Часть!. Язык С№ ) е1яе ( Еггг1ач = Сгпе; гегцгп О," ) ) Это аксессор яес. яес ( тт(о)т(1пбех)) ( а[тпбех) = ча1це; Еггугач = Га1яе; ) е1яе Етгг1ао = Сгцег ) ) // Возвратить логическое значение сгце, если индекс находится в установленных границах. рттчаСе Ьоо1 ох(япС [паек) ( 11(1паех >= 0 а 1пбех < Ьепогь) теоцгп СгцеГ тегогп Еа1ве) ) ) // Продемонстрировать применение отказоустойчивого массива. с1авв Гтпа1ГЗОешо ( ягагтс чоха Матп() ( Га11эотгягтау Ев = лен Га11эоегягтау(5); // Использовать свойство Етгог.