int upperBound; // наибольший индекс
Переменная а
служит для обращения к базовому массиву по ссылке. Память для него распределяется конструктором класса RangeArray
. Нижняя граница индексирования массива хранится в переменной lowerBound
, а верхняя граница — в переменной upperBound
.
Далее объявляются автоматически реализуемые свойства Length
и Error
.
// Автоматически реализуемое и доступное
//только для чтения свойство Length,
public int Length { get; private set; }
// Автоматически реализуемое и доступное
//только для чтения свойство Error,
public bool Error { get; private set; }
Обратите внимание на то, что в обоих свойства аксессор set
обозначен как private
. Как пояснялось выше, такое объявление автоматически реализуемого свойства, по существу, делает его доступным только для чтения.
Ниже приведен конструктор класса RangeArray
.
// Построить массив по заданному размеру,
public RangeArray(int low, int high) {
high++;
if(high <= low) {
Console.WriteLine("Неверные индексы");
high = 1; // создать для надежности минимально допустимый массив
low = 0;
}
а = new int[high - low];
Length = high - low;
lowerBound = low;
upperBound = --high;
}
При конструировании объекту класса RangeArray
передается нижняя граница массива в качестве параметра low
, а верхняя граница — в качестве параметра high
. Затем значение параметра high
инкрементируется, поскольку пределы индексирования массива изменяются от low
до high
включительно. Далее выполняется следующая проверка: является ли верхний индекс больше нижнего индекса. Если это не так, то выдается сообщение об ошибке и создается массив, состоящий из одного элемента. После этого для массива распределяется память, а ссылка на него присваивается переменной а
. Затем свойство Length
устанавливается равным числу элементов массива. И наконец, устанавливаются переменные lowerBound
и upperBound
.
Далее в классе RangeArray
реализуется его индексатор, как показано ниже.
// Это индексатор для класса RangeArray.
public int this[int index] {
// Это аксессор get.
get {
if(ok(index) ) {
Error = false;
return a[index - lowerBound];
}
else {
Error = true;
return 0;
}
}
// Это аксессор set.
set {
if(ok(index)) {
a[index - lowerBound] = value;
Error = false;
}
else
Error = true;
}
}
Этот индексатор подобен тому, что использовался в классе FailSoftArray
, за одним существенным исключением. Обратите внимание на следующее выражение, в котором индексируется массив а
.
index - lowerBound
В этом выражении индекс, передаваемый в качестве параметра index
, преобразуется в индекс с отсчетом от нуля, пригодный для индексирования массива а
. Данное выражение действует при любом значении переменной lowerBound
: положительном, отрицательном или нулевом.
Ниже приведен метод ok().
// Возвратить логическое значение true, если
// индекс находится в установленных границах,
private bool ok(int index) {
if(index >= lowerBound & index <= upperBound) return true;
return false;
}
Этот метод аналогичен использовавшемуся в классе FailSoftArray
, за исключением того, что в нем контроль границ массива осуществляется по значениям переменных lowerBound
и upperBound
.
Класс RangeArray
демонстрирует лишь одну разновидность специализированного массива, который может быть создан с помощью индексаторов и свойств. Существуют, конечно, и другие. Аналогичным образом можно, например, создать динамические массивы, которые расширяются или сужаются по мере надобности, ассоциативные и разреженные массивы. Попробуйте создать один из таких массивов в качестве упражнения.
ГЛАВА 11 Наследование