Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
10
Добавлен:
21.05.2015
Размер:
9.83 Кб
Скачать

Индексация массивов реализуется с использованием оператора" [ ]". В своих классах можно перегрузить его, но не прибегая к "услугам" метода operator(), а посредством создания индексатора(indexer). Индексатор позволяет обеспечить индексированный доступ к объекту. Главное назначение индексаторов —поддержать создание специализированных массивов, на которые налагается одно или несколько ограничений. При этом индексаторы можно использовать в синтаксисе, подобном реализованному в массивах. Индексаторы могут характеризоваться одной или несколькими размерностями.

Одномерный индексатор имеет следующий формат.

тип_элемента this[int индекс] {

// Аксессор считывания данных,

get {

// Возврат значения, заданного элементом индекс.

}

// Аксессор установки данных,

set {

// Установка значения, заданного

// элементом индекс.

}}

Здесь тип_элемента — базовый тип индексатора. Таким

образом, тип_элемента — это тип каждого элемента, к которому предоставляется доступ посредством индексатора. Он соответствует базовому типу массива. Параметр индекс получает индекс опрашиваемого (или устанавливаемого) элемента. Строго говоря, этот параметр не обязательно должен иметь тип int, но поскольку индексаторы обычно используются для обеспечения индексации массивов, целочисленный тип —наиболее подходящий.

В теле индексатора определяются два аксессора (средства доступа) с именами get иset. Аксессорподобен методу за исключением того, что в нем отсутствует объявлениетипа возвращаемого значения и параметров. При использовании индексатора аксессоры вызываются автоматически, и в качестве параметра оба аксессора принимают индекс. Если индексатор стоит слева от оператора присваивания, вызывается аксессорset и устанавливается элемент, заданный параметром индекс. В противном случае вызываетсяаксессорget и возвращается значение, соответствующее параметру индекc. Метод set также получает значение (именуемое value), которое присваивается элементу массива, найденному по заданному индексу.

Одно из достоинств индексатора состоит в том, что он позволяет точно управлять характером доступа к массиву, "отбраковывая" попытки некорректного доступа. Рассмотрим пример. В следующей программе класс FailSoftArray реализует массив, который "вылавливает" ошибки нарушения границ, предотвращая возникновение исключительных ситуаций. Это достигается за счет инкапсуляции массива как закрытого члена класса и осуществления доступа к этому массиву только через индексатор.

// Использование индексатора для создания

// отказоустойчивого массива.

using System;

classFailSoftArray {

int[] a; // Ссылканамассив.

publicint Length; // Length - открытыйчлен.

publicboolerrflag; // Индикаторрезультата

// последней операции.

// Создаем массив заданного размера,

publicFailSoftArray(int size) {

a = new int[size];Length = size;}

// Это - индексатор для класса FailSoftArray.

publicint 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;}

elseerrflag = true;}

}

// Методвозвращаетзначениеtrue, если

// индекс - в пределах границ,

privatebool ok(int index) {

if(index >= 0 & index < Length) return true;

returnfalse;

}

}

// Демонстрируемотказоустойчивыймассив,

classFSDemo {

public static void Main() {

FailSoftArrayfs = new FailSoftArray(5);

int x;

Console.WriteLine("Мягкоеприземление. ") ;

for(inti=0; i< (fs.Length * 2) ;i++)fs[i] = i*10;

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

{x = fs[i];if(x != -1) Console.Write(x + " ") ;}

Console.WriteLine();

// Теперь генерируем некорректный доступ.

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

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

fs[i] * i*10;if(fs.errflag)

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

}

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

x = fs[i] ;if(!fs.errflag) Console.Write(x + " " ) ;

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

}

}

}

При выполнении этой программы получаем такие результаты:

"Мягкое приземление".

0 10 20 30 40 0 0000

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

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] вне границ

Аксессорget предотвращает ошибки нарушения границ. Если заданный индекс находится в пределах границ, аксессорget возвращает элемент, соответствующий этому индексу. А если переданный индекс выходит за пределы границ, операции с массивом не выполняются, но и ничего страшного при этом не происходит. В данной версии класса FailSoftArray переменная errflag содержит результат выполнения каждой операции. Чтобы узнать, как завершилась очередная операция, достаточно проанализировать это поле.

Аксессорset () предотвращает ошибки нарушения границ. Если заданный индекс находится в пределах границ, значение, переданное через переменнуюvalue, присваивается соответствующему элементу массива. В противном случае признак ошибки errflagустанавливается равным значениюtrue.

Индексаторы необязательно создавать с поддержкой как get-, так и set-аксессоров. Можно создать индексатор, предназначенный только для чтения, реализовав лишь get-аксессор. И точно также можно создать индексатор, предназначенный только для записи, реализовав лишь set-аксессор.

Индексаторы можно перегружать. Чаще всего индексатор перегружается, чтобы иметь возможность использовать объект класса в качестве индекса, значение которого вычисляется специальным образом.

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

На использование индексаторов накладывается два ограничения. Во-первых, поскольку в индексаторе не определяется область памяти, получаемое индексатором значение нельзя передавать методу в качестве ref- или out-параметра. Во-вторых, индексатор должен быть членом экземпляра своего класса, поэтому его нельзя объявлять с использованием ключевого слова static.

Можно создавать индексаторы и для многомерных массивов.