Г. Шилдт - С#4.0 Полное руководство (1160795), страница 60
Текст из файла (страница 60)
Гог(1пг с=О) т < Гв.ьепось + 1) т++) ( Гв[1) = 1*10) 11(15.Етгог) Сопяо1е.нт1Сепьпе("Ошибка в индексе " + т) ) Создание свойства Еггог стало причиной двух следующих изменений в классе ра11БоГСЛттау. Во-первых, переменная Еггр1ао была сделана закрытой, поскольку теперь она служит базовым местом хранения данных для свойства еттог, а следовательно, она не должна быль доступна непосредственно. И во-вторых, было введено свойство Е г гог "только для чтения".
Теперь свойство Е г го г будет опрашиваться в тех программах, где требуется организовать обнаружение ошибок. Именно это и было продемонстрировано выше в методе Матп (), где намеренно сгенерирована ошибка нарушения границ массива, а для ее обнаружения использовано свойство Еггог. Автоматически реализуемые свойства Начиная с версии С() 3.0, появилась возможность для реализации очень простых свойств, не прибегая к явному определению переменной, которой управляет свойство. Вместо этого базовую переменную для свойства автоматически предоставляет компилятор.
Такое свойство называется автомап)ически реализуемым и принимает следующую обшую форму: Глава 10. Индексаторы и свойства 319 тип имя ( деш зею ) где тип обозначает конкретный тип свойства, а имя — присваиваемое свойству имя. Обратите внимание на то, что после обозначений аксессоров оес и вес сразу же следует точка с запятой, а тело у них отсутствует. Такой синтаксис предписывает компилятору создать автоматически переменную, иногда еще называемую поддерживающим полем, для хранения значения.
Такая переменная недосгупна непосредственно и не имеет имени. Но в то же время она может быть доступна через свойство. Ниже приведен пример объявления свойства, автоматически реализуемого под именем Пзегооппб. рпЫ1о ьпс Пвегооппс ( Чем неш ) Как видите, в этой строке кода переменная явно не объявляется. И как пояснялось выше, компилятор автоматически создает анонимное поле, в котором хранится значение. А в остальном автоматически реализуемое свойство Пзегеоипб подобно всем остальным свойствам. Но в отличие от обычных свойств автоматически реализуемое свойство не может быть доступным только для чтения или только для записи.
При объявлении этого своиства в любом случае необходимо указывать оба аксессора — оеб и зес. Хотя добиться желаемого (т.е. сделать автоматически реализуемое свойство доступным только для чтения или только для записи) все же можно, объявив ненужный аксессор как рг1уабе (подробнее об этом — в разделе "Применение модификаторов доступа в аксессорах"). Несмотря на очевидные удобства автоматически реализуемых свойств, их применение ограничивается в основном теми ситуациями, в которых не требуется управление установкой или получением значений из поддерживающих полей.
Напомним, что поддерживающее поле недоступно напрямую. Это означает, что на значение, ко~орое может иметь автоматически реализуемое свойство, нельзя наложить никаких ограничений. Следовательно, имена автоматически реализуемых свойств просто заменяют собой имена самих полей, а зачастую именно это и требуется в программе. Автоматически реализуемые свойства могут оказаться полезными и в тех случаях, когда с помощью свойств функциональные возможности программы открывак)тся для сторонних пользователей, и для этой цели могут даже применяться специальные средства проектирования.
Применение инициализаторов объектов в свойствах Как пояснялось в главе 8, иии((иалнзап(ор объекта применяется в качестве альтернативы явному вызову конструктора при создании объекта. С помощью инициализаторов объектов задаются начальные значения полей или свойств, которые требуется инициализировать. При этом синтаксис инициализаторов объектов оказывается одинакбвым как для свойств, так и для полей. В качестве примера ниже приведена программа из главы 8, измененная с целью продемонстрировать применение инициализаторов объектов в свойствах. Напомним, что в версии этой программы из главы 8 использовались поля, а приведенная ниже версия отличается лишь тем, что в ней поля Соппс и Бсг превращены в свойства.
В то же время синтаксис инициализаторов объектов не изменился. Применить инипиапиваторы объектов в свойствах. пв1по Зузгепм 320 часть (. язык С№ о1азз МуС1азз ( // Теперь это свойства. роЬ1ьс ьпС Сонно ( деС; зеС; ) роЬ11о зсг1пд Ясс ( дес; зес; ) ) о1азз ОЬ)1пьвоешо ( зкаоьо тома Маги () ( !/ Сконструировать объект типа МуС1азз с поиошью инипиапизаторов объектов. МуС1азз оЬ) пен МуС1азз ( СоппС = 100, ЯСс = "Тестирование" Сопзо1е.игьзеъьпе(оЬЯ.СопрС ь " " + оЬз.якг); ) ) Как видике, свойства соппс и ясг устанавливаютсн в выражениях с инициализатором объекта. Приведенная выше программа дает такой же результат, как и программа из главы 8, а именно: 100 Тестирование Как пояснялось в главе 8, синтаксис инициализатора объекта оказывается наиболее пригодным для работы с анонимными типами, формируемыми в (.Пх(( )-выражениях.
А в остальных случаях чаще всего используется синтаксис обычных конструкторов. Ограничения, присущие свойствам Свойствам присущ ряд существенных ограничений. Во-первых, свойство не определяет место для хранения данных, и поэтому не может быть передано методу в качестве параметра ге Т или опс. Во-вторых, свойство не подлежит перегрузке. Наличие двух разных свойств с доступом к одной и той же переменной допускается, но это, скорее, исключение, чем правило.
И наконец, свойство не должно изменять состояние базовой переменной при вызове аксессора пес. И хотя это ограничительное правило не соблюдается компилятором, его нарушение считается семантической ошибкой. Действие аксессора оеС не должно носить характер вме|пательства в функционирование переменной. Применение модификаторов доступа в аксессорах По умолчанию доступность аксессоров зес и оес оказывается такой же, как и у индексатора и свойства, частью которых они являются. Так, если свойство объявляется как рпь1ьс, то по умолчанию его аксессоры зес и оес также становятся открытыми (рпЬ11с).
Тем не менее для аксессора зес или оес можно указать собственный модификатор доступа, например ргьуасе. Но в любом случае доступность аксессора, определяемая таким модификатором, должна быть более ограниченной, чем доступность, указываемая для его свойства или индексатора. Существует целый ряд причин, по которым требуется ограничить доступность аксессора. Допустим, что требуется предоставить свободный доступ к значению свойства, Глава 10. Индексаторы и свойства 321 но вместе с тем дать возможность устанавливать это свойство только членам его класса. Для этого достаточно объявить аксессор данного свойства как рг1чаге. В приведенном ниже примере используется свойство Мургор, аксессор зег которого указан как ргачасе.
Применить модификатор доступа в аксессоре. пяьпч Зуя'ьеш; с1авя Ргорвссевя ( ьпс ргор; // поле, управляемое свойством МуРгор рпЬ11с Ргорассеяя() ( ргор = 0; ) /* Это свойство обеспечивает доступ к закрытой переменной экземпляра ргор. Оно разрешает получать значение переменной ргор иэ любого кода, но устанавливать его — только членам своего класса. */ рсЬ11с зппп МРРгор ( оес ( гегсгп ргор! ) ргьчаге яег ( !/ теперь это закрытый аксессор ргор = ча1че; ) ) // Этот член класса инкрементирует значение свойства Мургор.
рпЬ11с чогс) 1псгРгор() ( МуРгорь+1 // Допускается в том же самом классе. ) ) // Продемонстрировать применение модификатора доступа в аксессоре свойства. с1аяя Ргордссеяяоешо ( ясая1с тога Маьп() ( Ргордссеяя оЬ = пен Ргордссеяя()1 Сопяо1е.хг1геЬ1пе("Первоначальное значение оЬ.Мургор: " т оЬ.Мургор) оЬ.МуРгор = 100; /! недоступно для установки оЬ.1псгргор(); Сопяо1е.иг1севгпе("Значение оЬ.Мургор после инкрементирования: оЬ.Мургор); В классе Ргор)(осе я я аксессор яег указан как рг1чаге.
Это означает, что он доступен только другим членам данного класса, например методу 1 пег Р гор ( ), но недоступен для кода за пределами класса Ргорйссеяя. Именно поэтому попытка Присвоить свойству оЬ. Мургор значение в классе РгорАссеяя()ето закомментирована. Вероятно, ограничение доступа к аксессорам оказывается наиболее важным для работы с автоматически реализуемыми свойствами.
Как пояснялось выше, создать 322 Часть!. Язык С№ автоматически реализуемое свойство только для чтения или же только для записи нельзя, поскольку оба аксессора, дег и яес, должны быть указаны при объявлении такого свойства. Тем не менее добиться желаемого результата все же можно, объявив один из аксессоров автоматически реализуемого свойства как рт1чабе. В качестве примера ниже приведено объявление автоматически реализуемого свойства Ьепдсп для класса Га11ЯоЕГАттау, которое фактически становится доступным только для чтения.
рпЫгс гпс Ьепдсп ( дес; ртгчасе яес; ) Свойство ЬепдГЬ может быть установлено только из кода в его классе, поскольку его аксессор яес объявлен как рг1часе. А изменять свойство Ьепдсн за пределами его класса не разрешается. Это означает, что за пределами своего класса свойство, по существу, оказывается доступным только для чтения. Аналогичным образом можно объявить и свойство Егтог, как показано ниже. роЫ1с Ьоо1 Еггот ( дес; ргтчасе яесг Благодаря этому свойство Еггот становится доступным для чтения, но не для установки за пределами класса Га11Яо ГГАттау. Для опробования автоматически реализуемых вариантов свойств ЬепдГЬ и Етгот в классе Га11БоГГАгтау удалим сначала переменные 1еп и Еттр1ад, поскольку они больше не нужны, а затем заменим каждое применение переменных 1еп и Еттр1ад свойствами ЬепдГЬ и Ет гот в классе Гаг1Яо ГГАттау.