KnigaRead.com/
KnigaRead.com » Разная литература » Прочее » Герберт Шилдт - C# 4.0 полное руководство - 2011

Герберт Шилдт - C# 4.0 полное руководство - 2011

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн "Герберт Шилдт - C# 4.0 полное руководство - 2011". Жанр: Прочее издательство неизвестно, год неизвестен.
Перейти на страницу:

Применение индексаторов и свойств

В предыдущих примерах программ был продемонстрирован основной принцип действия индексаторов и свойств, но их возможности не были раскрыты в полную силу. Поэтому в завершение этой главы обратимся к примеру класса RangeArray, в котором индексаторы и свойства используются для создания типа массива с пределами индексирования, определяемыми пользователем.

Как вам должно быть уже известно, индексирование всех массивов в C# начинается с нуля. Но в некоторых приложениях индексирование массива удобнее начинать с любой произвольной точки отсчета: с 1 или даже с отрицательного числа, например от -5 и до 5. Рассматриваемый здесь класс RangeArray разработан таким образом, чтобы допускать подобного рода индексирование массйвов.

Используя класс RangeArray, можно написать следующий фрагмент кода.

RangeArray га = new RangeArray(-5, 10); // массив'с индексами от -5 до 10 for(int i=-5; i <= 10; i++) ra[i] = i; // индексирование массива от -5 до

10

Нетрудно догадаться, что в первой строке этого кода конструируется объект класса RangeArray с пределами индексирования массива от -5 до 10 включительно. Первый аргумент обозначает начальный индекс, а второй — конечный индекс. Как только объект га будет сконструирован, он может быть проиндексирован как массив в пределах от -5 до 10.

Ниже приведен полностью класс RangeArray вместе с классом RangeArrayDemo, в котором демонстрируется индексирование массива в заданных пределах. Класс RangeArray реализован таким образом, чтобы поддерживать массивы типа int, но при желании вы можете изменить этот тип на любой другой.

/* Создать класс со специально указываемыми пределами индексирования массива. Класс RangeArray допускает индексирование массива с любого значения, а не только с нуля. При создании объекта класса RangeArray указываются начальный и конечный индексы. Допускается также указывать отрицательные индексы. Например, можно создать массивы, индексируемые от -5 до 5, от 1 до 10 или же от 50 до 56. */

using System;

class RangeArray {

// Закрытые данные.

int[] а; // ссылка на базовый массив int lowerBound; // наименьший индекс int upperBound; // наибольший индекс

// Автоматически реализуемое и доступное только для чтения свойство Length, public int Length { get; private set; }

// Автоматически реализуемое и доступное только для чтения свойство Error, public bool Error { get; private set; }

// Построить массив по заданному размеру, 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. 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;

}

}

// Возвратить логическое значение true, если // индекс находится в установленных границах, private bool ok(int index) {

if(index >= lowerBound & index <= upperBound) return true; return false;

}

}

// Продемонстрировать применение массива с произвольно // задаваемыми пределами индексирования, class RangeArrayDemo { static void Main() {

RangeArray ra = new RangeArray(-5, 5);

RangeArray ra2 = new RangeArray(1, 10);

RangeArray ra3 = new RangeArray(-20, -12);

// Использовать объект га в качестве массива.

Console.WriteLine("Длина массива га: " + га.Length); for(int i = -5; i <= 5; i++)

га[i] = i;

Console.Write("Содержимое массива га: "); for(int i = -5; i <= 5; i++)

Console.Write(ra[i] + " ");

Console.WriteLine("n");

// Использовать объект ra2 в качестве массива.

Console.WriteLine("Длина массива га2: " + ra2.Length); for(int i = 1; i <= 10; i++) ra2[i] = i;

Console.Write("Содержимое массива ra2: "); for(int i = 1; i <= 10; i++)

Console.Write(ra2[i] + " ") ;

Console.WriteLine("n") ;

// Использовать объект гаЗ в качестве массива.

Console.WriteLine("Длина массива гаЗ: " + гаЗ.Length); for(int i = -20; i <= -12; i++) ra3[i] = i;    >

Console.Write("Содержимое массива гаЗ: "); for (int i = -20; i <= -12; i++)

Console.Write(ra3[i] + " ");

Console.WriteLine("n") ;

}

}

При выполнении этого кода получается следующий результат.

Длина массива га: 11

Содержимое массива га: -5-4-3-2-1012345 Длина массива га2: 10

Содержимое массива га2: 12345678910 Длина массива гаЗ: 9

Содержимое массива гаЗ: -20 -19 -18 -17 -16 -15 -14 -13 -12

Как следует из результата выполнения приведенного выше кода, объекты типа RangeArray можно индексировать в качестве массивов, начиная с любой точки отсчета, а не только с нуля. Рассмотрим подробнее саму реализацию класса RangeArray.

В начале класса RangeArray объявляются следующие закрытые переменные экземпляра.

// Закрытые данные.

int[] а; // ссылка на базовый массив int lowerBound; // наименьший индекс •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;

}

}

Этот индексатор подобен тому, что использовался в классе FailSof tArray, за одним существенным исключением. Обратите внимание на следующее выражение, в котором индексируется массив а.

index - lowerBound

В этом выражении индекс, передаваемый в качестве параметра index, преобразуется в индекс с отсчетом от нуля, пригодный для индексирования массива а. Данное выражение действует при любом значении переменной lowerBound: положительном, отрицательном или нулевом.

Ниже приведен метод ok ().

// Возвратить логическое значение true, если // индекс находится в установленных границах, private bool ok(int index) {

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*