Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Заочники_АСОИ / Лекции / 01 Классы / Объекты и типы.docx
Скачиваний:
20
Добавлен:
29.02.2016
Размер:
97.14 Кб
Скачать

Листинг 1.

// Использовать индексатор для создания отказоустойчивого массива

using System;

class FailSoftArray

{

int[] a; // ссылка на базовый массив

public int Length; // открытая переменная длины массива

public bool ErrFlag; // обозначает результат последней операции

// Построить массив заданного размера

public FailSoftArray(int size)

{

a = new int[size];

Length = size;

}

// Это индексатор для класса 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 FSDemo

{

static void Main()

{

FailSoftArray fs = new FailSoftArray(5);

int x;

// Выявить скрытые сбои

Console.WriteLine("Скрытый сбой.");

for(int i=0; i < (fs.Length * 2); i++)

fs[i] = i*10;

for(int i=0; i < (fs.Length * 2); i++)

{

x = fs[i];

if(x != -1) Console.Write(x + " ");

}

Console.WriteLine();

// А теперь показать сбои

Console.WriteLine("\nСбой с уведомлением об ошибках.");

for(int i=0; i < (fs.Length * 2); i++) {

fs[i] = i*10;

if(fs.ErrFlag)

Console.WriteLine("fs[" + i + "] вне границ");

}

for(int i=0; i < (fs.Length * 2); i++) {

x = fs[i];

if(!fs.ErrFlag) Console.Write(x + " ");

else

Console.WriteLine("fs[" + i + "] out-of-bounds");

}

}

}

Вот к какому результату приводит выполнение этой программы.

Скрытый сбой

0 10 20 30 40 0 0 0 0 0

Сбой с уведомлением об ошибках.

fs[5] вне границ

fs[6] вне границ

fs[7] вне границ

fs[8] вне границ

fs[9] вне границ

0 10 20 30 40

fs[5] вне границ

fs[6] вне границ

fs[7] вне границ

fs[8] вне границ

fs[9] вне границ

Индексатор препятствует нарушению границ массива. Внимательно проанализи­руем каждую часть кода индексатора. Он начинается со следующей строк.

public int this[int index]

{

В этой строке кода объявляется индексатор, оперирующий элементами типа int. Ему передается индекс в качестве параметра index. Кроме того, индексатор объявля­ется открытым (public), что дает возможность использовать этот индексатор в коде за пределами его класса.

Рассмотрим следующий код аксессора get.

get

{

if (ok(index))

{

ErrFlag = false;

return a[index];

}

else

{

ErrFlag = true;

return 0;

}

}

Аксессор get предотвращает ошибки нарушения границ массива, проверяя в пер­вую очередь, находится ли индекс в установленных границах. Эта проверка границ вы­полняется в методе ok(), который возвращает логическое значение true, если индекс правильный, а_иначе  логическое значение false. Так, если указанный индекс на­ходится в установленных границах, то по этому индексу возвращается соответствую­щий элемент. А если индекс оказывается вне установленных границ, то никаких опе­раций не выполняется, но в то же время не возникает никаких ошибок переполнения. В данном варианте класса FailSoftArray переменная ErrFlag содержит результат каждой операции. Ее содержимое может быть проверено после каждой операции на предмет удачного или неудачного выполнения последней. (Более совершенным способом обработки ошибок осуществляется с помощью имеющейся в C# под­системы обработки исключительных ситуаций, а до тех пор можно вполне обойтись установкой и проверкой признака ошибки.)

А теперь рассмотрим следующий код аксессора set, предотвращающего ошибки нарушения границ массива.

set

{

if(ok(index) )

{

a[index] = value;

ErrFlag = false;

}

else ErrFlag = true;

}

Если параметр index метода ok() находится в установленных пределах, то соот­ветствующему элементу массива присваивается значение, передаваемое из параметра value. В противном случае устанавливается логическое значение true переменной ErrFlag. Напомним, что value в любом аксессорном методе является неявным пара­метром, содержащим присваиваемое значение. Его не нужно (да и нельзя) объявлять отдельно.

Наличие обоих аксессоров, get и set, в индексаторе не является обязательным. Так, можно создать индексатор только для чтения, реализовав в нем один лишь аксес­сор get, или же индексатор только для записи с единственным аксессором set.

Перегрузка индексаторов

Индексатор может быть перегружен. В этом случае для выполнения выбирается тот вариант индексатора, в котором точнее соблюдается соответствие его параметра и аргумента, указываемого в качестве индекса. Ниже приведен пример программы, в ко­торой индексатор массива класса FailSoftArray перегружается для индексов типа double. При этом индексатор типа double округляет свой индекс до ближайшего целого значения.

Соседние файлы в папке 01 Классы