Шрифт:
Интервал:
Закладка:
}
}
// Свойство Error только для чтения,
public bool Error {
get {
return ErrFlag;
}
}
// Это индексатор для класса FailSoftArray.
public int this[int index] {
// Это аксессор get.
get {
if(ok(index)) {
ErrFlag = false;
return a[index];
}
else {
ErrFlag = true;
return 0;
}
}
// Это аксессор set.
set {
if(ok(index)) {
a[index] = value;
ErrFlag = false;
}
else
ErrFlag = true;
}
}
// Возвратить логическое значение true, если
// индекс находится в установленных границах,
private bool ok(int index) {
if(index >= 0 & index < Length) return true;
return false;
}
}
// Продемонстрировать применение отказоустойчивого массива,
class FinalFSDemo {
static void Main() {
FailSoftArray fs = new FailSoftArray(5);
// Использовать свойство Error,
for(int i=0; i < fs.Length + 1; i++) {
fs[i] = i * 10;
if(fs.Error)
Console.WriteLine("Ошибка в индексе " + i);
}
}
}
Создание свойства Error стало причиной двух следующих изменений в классе FailSoftArray. Во-первых, переменная ErrFlag была сделана закрытой, поскольку теперь она служит базовым местом хранения данных для свойства Error, а следовательно, она не должна быть доступна непосредственно. И во-вторых, было введено свойство Error "только для чтения". Теперь свойство Error будет опрашиваться в тех программах, где требуется организовать обнаружение ошибок. Именно это и было продемонстрировано выше в методе Main(), где намеренно сгенерирована ошибка нарушения границ массива, а для ее обнаружения использовано свойство Error.
Автоматически реализуемые свойстваНачиная с версии C# 3.0, появилась возможность для реализации очень простых свойств, не прибегая к явному определению переменной, которой управляет свойство. Вместо этого базовую переменную для свойства автоматически предоставляет компилятор. Такое свойство называется автоматически реализуемым и принимает следующую общую форму:
тип имя { get; set; }
где тип обозначает конкретный тип свойства, а имя — присваиваемое свойству имя. Обратите внимание на то, что после обозначений аксессоров get и set сразу же следует точка с запятой, а тело у них отсутствует. Такой синтаксис предписывает компилятору создать автоматически переменную, иногда еще называемую поддерживающим полем, для хранения значения. Такая переменная недоступна непосредственно и не имеет имени. Но в то же время она может быть доступна через свойство.
Ниже приведен пример объявления свойства, автоматически реализуемого под именем UserCount.
public int UserCount { get; set; }
Как видите, в этой строке кода переменная явно не объявляется. И как пояснялось выше, компилятор автоматически создает анонимное поле, в котором хранится значение. А в остальном автоматически реализуемое свойство UserCount подобно всем остальным свойствам.
Но в отличие от обычных свойств автоматически реализуемое свойство не может быть доступным только для чтения или только для записи. При объявлении этого свойства в любом случае необходимо указывать оба аксессора — get и set. Хотя добиться желаемого (т.е. сделать автоматически реализуемое свойство доступным только для чтения или только для записи) все же можно, объявив ненужный аксессор как private (подробнее об этом — в разделе "Применение модификаторов доступа в аксессорах").
Несмотря на очевидные удобства автоматически реализуемых свойств, их применение ограничивается в основном теми ситуациями, в которых не требуется управление установкой или получением значений из поддерживающих полей. Напомним, что поддерживающее поле недоступно напрямую. Это означает, что на значение, которое может иметь автоматически реализуемое свойство, нельзя наложить никаких ограничений. Следовательно, имена автоматически реализуемых свойств просто заменяют собой имена самих полей, а зачастую именно это и требуется в программе. Автоматически реализуемые свойства могут оказаться полезными и в тех случаях, когда с помощью свойств функциональные возможности программы открываются для сторонних пользователей, и для этой цели могут даже применяться специальные средства проектирования.
Применение инициализаторов объектов в свойствахКак пояснялось в главе 8, инициализатор объекта применяется в качестве альтернативы явному вызову конструктора при создании объекта. С помощью инициализаторов объектов задаются начальные значения полей или свойств, которые требуется инициализировать. При этом синтаксис инициализаторов объектов оказывается одинаковым как для свойств, так и для полей. В качестве примера ниже приведена программа из главы 8, измененная с целью продемонстрировать применение инициализаторов объектов в свойствах. Напомним, что в версии этой программы из главы 8 использовались поля, а приведенная ниже версия отличается лишь тем, что в ней поля Count и Str превращены в свойства. В то же время синтаксис инициализаторов объектов не изменился.
// Применить инициализаторы объектов в свойствах
using System;
// Применить инициализаторы объектов в свойствах.
class MyClass {
// Теперь это свойства,
public int Count { get; set; }
public string Str { get; set; }
}
class ObjlnitDemo {
static void Main() {
// Сконструировать объект типа MyClass с помощью инициализаторов объектов.
MyClass obj = new MyClass {
Count = 100, Str = "Тестирование" };
Console.WriteLine (obj.Count + " " + obj.Str);
}
}
Как видите, свойства Count и Str устанавливаются в выражениях с инициализатором объекта. Приведенная выше программа дает такой же результат, как и программа из главы 8, а именно:
100 Тестирование
Как пояснялось в главе 8, синтаксис инициализатора объекта оказывается наиболее пригодным для работы с анонимными типами, формируемыми в LINQ-выражениях. А в остальных случаях чаще всего используется синтаксис обычных конструкторов.
Ограничения, присущие свойствамСвойствам присущ ряд существенных ограничений. Во-первых, свойство не определяет место для хранения данных, и поэтому не может быть передано методу в качестве параметра ref или out. Во-вторых, свойство не подлежит перегрузке. Наличие двух разных свойств с доступом к одной и той же переменной допускается, но это, скорее, исключение, чем правило. И наконец, свойство не должно изменять состояние базовой переменной при вызове аксессора get. И хотя это ограничительное правило не соблюдается компилятором, его нарушение считается семантической ошибкой. Действие аксессора get не должно носить характер вмешательства в функционирование переменной.
Применение модификаторов доступа в аксессорах
По умолчанию доступность аксессоров set и get оказывается такой же, как и у индексатора и свойства, частью которых они являются. Так, если свойство объявляется как public, то по умолчанию его аксессоры set и get также становятся открытыми (public). Тем не менее для аксессора set или get можно указать собственный модификатор доступа, например private. Но в любом случае доступность аксессора, определяемая таким модификатором, должна быть более ограниченной, чем доступность, указываемая для его свойства или индексатора.
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- ИНФОРМАЦИОННАЯ ТЕХНОЛОГИЯ. РУКОВОДСТВО ПО УПРАВЛЕНИЮ ДОКУМЕНТИРОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ - ГОССТАНДАРТ РОССИИ - Программирование
- Управление исходными текстами. Часть 1. Краткое руководство по CVS - Илья Рыженков - Программирование
- Гибкое управление проектами и продуктами - Борис Вольфсон - Программирование
- Каждому проекту своя методология - Алистэр Коуберн - Программирование
- Разработка ядра Linux - Роберт Лав - Программирование
- Как спроектировать современный сайт - Чои Вин - Программирование
- Творческий отбор. Как создавались лучшие продукты Apple во времена Стива Джобса - Кен Косиенда - Прочая околокомпьтерная литература / Интернет / Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование