Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 59
Текст из файла (страница 59)
Для того чтобы убедиться в этом, попробуйте удалить символы комментария в начале следующей строки из приведенного выше кода: // тз.ьепОГЬ = 10; // Ошибка, запись запрещена! Глава )О. Индексвторы в свойства 303 При попытке скомпилировать данный код вы получите сообщение об ошибке, уведомляющее о том, что ьепосЬ является свойством, доступным только для чтения. Добавлением свойства ьепось в класс Га11Яогслггау усовершенствование рассматриваемого здесь примера кода с помощью свойств далеко не исчерпывается. Еще одним членом данного класса, подходящим для превращения в свойство, служит переменная еггГ1ас, поскольку ее применение должно быть ограничено только чтением.
ниже приведен окончательно усовершенствованный вариант класса Га11Яоггйггау, в котором создается свойство еггог, использующее в качестве места для хранения данных исходную переменную ЕггГ1ао, ставшую теперь закрытой. // Превратить переменную ЕггГ1ао в сВОйстВО. цв1пд Яувгещт с1авв Га11яовгйггау ( 1пг(] ат // ссылка на базовый массив 1пс 1епт // длина массива Ьоо1 Еггг1ачт // теперь это частная переменная, // обозначающая результат последней операции // Построить массив заданного размера. рцЬ11с Га11зовсаггау(гпг ввге) а = пен Ьпс(в1ге]т Ьеп = в1гет ) // Свойство Ьепчгп только для чтения.
рцЫЬс Ьпс Ьепчсп ( дев ( гесцгп 1епт // Свойство Еггог только для чтения. рцЫ1с Ьоо1 Еггог ( дев ( гегцгп ЕггГ1аог ) ) // Это индексатор для класса Га11зотгаггау. рцЫЬс 1пг СЫв(1пг Ьпбех] ( // Это аксессор дев. чес ( 11 (ох (Ьпбех) ) ( ЕггГ1ад = Га1вет геспгп а(гпбех]т ] е1ве ( ЕггГ1ад = Споет гегцгп От ) ) 304 Часть ). Язык С№ // Это аксессор яег. вес ( гв(ок(гпаех)) ( а(1паех] = ча1пе) ЕггГ1ач Га1яе/ ) е1ве ЕггГ1ад = Ггце/ ) ) // Возвратить логическое значение огне, если // индекс находится в установленных границах.
рггчаге Ьоо1 ок(1пс гпбех) ( 11(1паех >= 0 в 1паех < ьепчгь) гегцгп ггцег геснгп Га1вег ) // продемонстрировать применение отказоустойчивого массива. с1аяв Г1па1ГЗПешо ( всасгс тога Мвтп() ( Га11эотсаггау Гя = пен Га11эотсяггау(5)/ // Использовать свойство Еггог. Гог(гпс 1=0г г < Гв.ьепдсн + 1г 1++) ( гя(1] = 1*10г 1Г(тя.Еггог) Сопяо1е.нггсеьгпе("Ошибка в индексе " + г); Создание свойства Еггог стало причиной двух следующих изменений в классе Га11еоег))ггау. Во-первых, переменная еггГ1ад была сделана закрытой, поскольку теперь она служит базовым местом хранения данных для свойства еггог, а следовательно, она не должна быть доступна непосредственно.
И во-вторых, было введено свойство еггог только для чтения. Теперь свойство еггог будет опрашиваться в тех программах, где требуется организовать обнаружение ошибок. Именно это и было продемонстрировано выше в методе Магд (), где намеренно сгенерирована ошибка нарушения границ массива, а для ее обнаружения использовано свойство еггог. Автоматически реализуемые свойства В версии С№ 3.0 появилась возможность реализации очень простых свойств, не прибегая к явному определению переменной, которой управляет свойство.
Вместо этого базовую переменную для свойства автоматически предоставляет компилятор. Такое свойство называется автоматически реализуемым и принимает следующую общую форму: тид имя ( дегг яегг ) где тип обозначает конкретный тип свойства, а имя — присваиваемое свойству имя. Обратите внимание на то, что после обозначений аксессоров дес и вег сразу же следует точка с запятой, а тело у них отсутствует. Такой синтаксис предписывает компилятору Глава )О. Индвксвторы и свойства 305 автоматически создать переменную, иногда еще называемую поддерялшваюя)им полям, для хранения значения.
Такая переменная недоступна непосредственно и не имеет имени. Но в то же время она может быть доступна через свойство. Ниже приведен пример объявления свойства, автоматически реализуемого под именем ПяегСоппг. рпЫъс 1пс ОяегСоппг ) дег; яес; ) Как видите, в этой строке кода переменная явно не объявляется. И как пояснялось выше, компилятор автоматически создает анонимное поле, в котором хранится значение.
А в остальном автоматически реализуемое свойство пяе гсоипс подобно всем остальным свойствам. Но в отличие ог обычных свойств автоматически реализуемое свойство не может быть доступным только для чтения или только для записи. При объявлении этого свойства в любом случае необходимо указывать оба аксессора — дог и яес. Хотя добиться желаемого (т.е.
сделать автоматически реализуемое свойство доступным только для чтения или только для записи) все же можно, объявив ненужный аксессор как рг1чаге (подробнее об этом — в разделе "Применение модификаторов доступа в аксессорах"). Несмотря на очевидные удобства автоматически реализуемых свойств, их применение ограничивается в основном теми ситуациями, в которых не требуется управление установкой или получением значений из поддерживающих полей.
Напомним, что поддерживающее поле недоступно напрямую. Это означает, что на значение, которое может иметь автоматически реализуемое свойство, нельзя наложить никаких ограничений. Следовательно, имена автоматически реализуемых свойств просто заменяют собой имена самих полей, а зачастую именно это и требуется в программе. Автоматически реализуемые свойства могут оказаться полезными и в тех случаях, когда с помощью свойств функциональные возможности программы открываются для сторонних пользователей, и для этой цели могут даже применяться специальные средства проектирования. Применение инициализаторов объектов в свойствах Как пояснялось в главе 8, в версию Св) 3.0 было внедрено новое средство, называемое инициализаторам обьекта и применяемое в качестве альтернативы явному вызову конструктора при создании объекта.
С помощью инициализаторов объектов задаются начальные значения полей или свойств, которые требуется инициализировать. При этом синтаксис инициализаторов объектов оказывается одинаковым как для свойств, так и для полей. В качестве примера ниже приведена программа из главы 8, переделанная с целью продемонстрировать применение инициализаторов объектов в свойствах. Напомним, что в версии этой программы из главы 8 использовались поля, а приведенная ниже версия отличается лишь тем, что в ней поля сорос и ясг превращены в свойства. В то же время синтаксис инициализаторов объектов не изменился. // Применить иниииалиэаторы объектов в свойствах.
ия1пд Буясевп с1яяя МуС1яяя ) // Теперь ято свойства. рпЬ11с 1пг Соипг ) дегг яес; рпЫ1с яггъпд Эсг ) детю яес; ) ) 306 Часть (. Язык С№ с1аяя ОЬ01пьгпещо ( ягагьс чо10 Маьп() ( // Сконструировать объект типа МуС1аяя с помощью // инндиалняатороа объектов. МуС1аяя опав = пен МуС1аяя ( Соопк = 100, экг = "Тестирование" )Г Сопяо1е.ыгъсеь№пе(оЬТ.Соопк'+ " " + оЬЗ.БСг)к ) ) Как видите, свойства соипс и зсг устанавливаются в выражениях с ииициализатором объекта. Приведенная выше программа дает такой же результат, как и программа из главы 8, а именно: 100 Тестирование Как пояснялось в главе 8, синтаксис ииициализатора объекта оказывается наиболее пригодным для работы с анонимными типами, формируемыми в (.ПЩ-вырюкеииях.
А в остальиых случаях чаще всего используется синтаксис обычных конструкторов. Ограничения, присущие свойствам Свойствам присущ ряд существенных ограничений. Во-первых, свойство ие определяет место для хранения данных, и поэтому ие может быть передано методу в качестве параметра гег или опг. Во-вторых, свойство ие подлежит перегрузке. Наличие двух разных свойств с доступом к одной и той же переменной допускается, ио это скорее исключение, чем правило. И наконец, свойство ие должно изменять состояние базовой переменной при вызове аксессора дес.
И хотя это ограничительное правило ие соблюдается компилятором, его нарушение считается семантической ошибкой. Действие аксессора Пес ие должно носить характер вмешательства в функционирование переменной. Применение модификаторов доступа в аксессорах По умолчанию доступность аксессоров яес и дес оказывается такой же, как и у иидексатора и свойства, частью которых оии являются.
Так, если свойство объявляется как рпЬ11с, то по умолчанию его аксессоры яес и дег также становятся открытыми (рпЬ110). Тем ие менее для аксессора яеь или дег можно указать собственный модификатор доступа, например ргъчаге. Но в любом случае доступность аксессора, определяемая таким модификатором, должна быть более ограниченной, чем доступность, указываемая для его свойства или иидексатора. Существует целый ряд причин, по которым требуется ограничить доступность аксессора. Допустим, что требуется предоставить свободный доступ к значению свойства, ио вместе с тем дать возможность устанавливать это свойство только членам его класса. Для этого достаточно объявить аксессор данного свойства как рг1чаге.
В приведенном ниже примере используется свойство Мургор, аксессор яес которого указан как ргъчасе. // Применить модификатор доступа я аксессоре. Глава )О. Мндвксвторы н свойства 307 извод Яуэгеш( с1аэз РгорАссеэз ( тпс ргорт // поле, управляемое свойством МуРгор риьтйс РгорАссеэз() ( ргор = от ) /* Зто свойство обеспечивает доступ к закрытой переменной экземпляра ргор. Оно разрешает получать значение переменной ргор из любого кода, но устанавливать его — только членам своего класса. */ риьтгс гпс Мургор ( цег ( гесигп ргорт ) ргтчасе зес ( // теперь это закрытый аксессор ргор = на1иет ) // Этот член класса инкрементирует значение // свойства МуРгор. риьтгс чотб тпсгРгор() ( МуРгор++к // допускается з том ке самом классе.
) // Продемонстрировать применение модификатора доступа // э аксессоре свойства. с1аэз РгорАссезвОешо ( эсасгс уогб Маги() ( РгорАссевв оЬ = пеи Ргорлссезз()! Сопзо1е.нгтгеътпе("Первоначальное значение оЬ.Мургор: " + оЬ.Мургор)т // оЬ.Мургор = 100т // недоступно для установки оь.1псгРгор()т Сопзо1е.нгтсеътпе("Значение оЬ.Мургор после " + "инкрементирозания: " + оЬ.Мургор)т В классе Ргорйссезэ аксессор эес указан как рг1часе.
Это означает, что ои доступеи только другим членам данного класса, например методу 1псгргор (), ио недоступен для кода за пределами класса РгорАссе аз. Именно поэтому попытка присвоить свойству оЬ. МуРгор значение в классе РгорАссеаз Репо закоммеитироваиа. Вероятно, ограничение доступа к аксессорам оказывается наиболее важным для работы с автоматически реализуемыми свойствами. Как пояснялось выше, создать автоматически реализуемое свойство только для чтения или же только для записи нельзя, поскольку оба аксессора, Пег и зег, должны быть указаны при объявлении такого свойства.