Volatile 10 страница
class A class B: A свойство P класса B скрывает свойство P класса A по отношению к операциям чтения и записи. Таким образом, в операторах B b = new B(); присваивание свойству b.P вызывает ошибку времени компиляции, поскольку свойство только для чтения P класса B скрывает свойство только для записи P класса A. Обратите внимание, что для доступа к скрытому свойству P можно использовать приведение. В отличие от открытых полей свойства обеспечивают разделение между внутренним состоянием объекта и его открытым интерфейсом. Рассмотрим пример: class Label public Label(int x, int y, string caption) { public int X { public int Y { public Point Location { public string Caption { В этом примере в классе Label используется два поля типа int (x и y) для хранения местоположения надписи. Сведения о местоположении предоставляются открытым образом в виде свойств X и Y, а также свойства Location типа Point. Если в последующих версиях класса Label потребуется внутреннее хранение данных о местоположении с помощью типа Point, это можно реализовать, не внося изменения в открытый интерфейс класса: class Label public Label(int x, int y, string caption) { public int X { public int Y { public Point Location { public string Caption { Если бы свойства x и y были полями public только для чтения, внести такие изменения в класс Label было бы невозможно. Предоставление состояния с помощью свойств не обязательно является менее эффективным, чем непосредственное предоставление полей. В частности, если невиртуальное свойство содержит небольшой объем кода, в среде выполнения вызовы его методов доступа могут быть заменены фактическим кодом методов доступа. Этот процесс называется встраиванием и обеспечивает эффективность обращения к свойству на уровне обращения к полю, сохраняя при этом повышенную гибкость свойств. Поскольку вызов метода доступа get концептуально равнозначен чтению значения поля, не рекомендуется, чтобы при использовании методов доступа get выполнялись видимые побочные действия. В примере class Counter public int Next { значение свойства Next зависит от числа выполненных обращений к нему. Таким образом, обращение к свойству порождает заметные побочные действия, поэтому в этом случае свойство необходимо реализовывать как метод. Соглашение об отсутствии побочных действий для методов доступа get не означает, что методы доступа get всегда должны использоваться только для возвращения значений, хранящихся в полях. В действительности методы доступа get часто используются для вычисления значения свойства посредством обращения к нескольким переменным или вызова методов. Однако правильно разработанный метод доступа get не выполняет действий, вызывающих заметные изменения в состоянии объекта. Свойства можно использовать для задержки инициализации ресурса до того момента времени, когда на него будет сделана первая ссылка. Например: using System.IO; public class Console public static TextReader In { public static TextWriter Out { public static TextWriter Error { Класс Console содержит три свойства (In, Out и Error), которые представляют стандартные устройства ввода, вывода и вывода ошибок соответственно. Благодаря предоставлению этих членов в виде свойств класса Console обеспечивается задержка их инициализации до момента фактического использования. Например, при первой ссылке на свойство Out, как показано в примере Console.Out.WriteLine("Привет!"); создается базовый объект TextWriter для устройства вывода. Однако если приложение не ссылается на свойства In и Error, объекты для этих устройств не создаются. 10.7.3 Автоматически реализуемые свойства Для свойства, определенного как автоматически реализуемое свойство, автоматически создается скрытое резервное поле, для которого реализуются методы доступа для чтения и записи. Следующий пример: public class Point { равнозначен следующему объявлению: public class Point { Поскольку резервное поле недоступно, чтение и запись его значений осуществляются только с помощью методов доступа свойства. Это означает, что автоматически реализуемые свойства только для чтения или только для записи не имеют смысла и не разрешены. Однако возможно задать различные уровни доступа для каждого из методов доступа. Таким образом, можно имитировать свойство только для чтения с закрытым резервным полем следующим образом: public class ReadOnlyPoint { Это ограничение также означает, что явное присваивание типов структуры автоматически реализуемым свойствам может осуществляться только с помощью стандартного конструктора структуры, поскольку для присваивания самого свойства требуется явное присваивание структуры. Это означает, что пользовательские конструкторы должны вызывать конструкторы по умолчанию. 10.7.4 Доступность; Если метод доступа содержит модификатор_метода_доступа, область доступности (§3.5.2) метода определяется на основании объявленной доступности модификатора_метода_доступа. Если метод доступа не содержит модификатор_метода_доступа, область доступности метода определяется на основании объявленной доступности свойства или индексатора. Наличие модификатора_метода_доступа никогда не влияет на поиск членов (§7.3) или разрешение перегрузки (§7.4.3). Модификаторы свойства или индексатора всегда определяют связанные свойство или индексатор независимо от контекста доступа.
|