Страница 134 из 502
<b>тип_элемента this[int индекс] {</b>
<b> // Аксессор для получения данных, get {</b>
<b> // Возврат значения, которое определяет индекс.</b>
}
<b> // Аксессор для установки данных, set {</b>
<b> // Установка значения, которое определяет индекс.</b>
<b> }</b>
<b>}</b>
где тип_элемента обозначает конкретный тип элемента индексатора. Следовательно, у каждого элемента, доступного с помощью индексатора, должен быть определенный тип_элемента. Этот тип соответствует типу элемента массива. Параметр индекс получает конкретный индекс элемента, к которому осуществляется доступ. Формально этот параметр совсем не обязательно должен иметь тип int, но поскольку индексаторы, как правило, применяются для индексирования массивов, то чаще всего используется целочисленный тип данного параметра.
В теле индексатора определены два аксессора (т.е. средства доступа к данным): get и set. Аксессор подобен методу, за исключением того, что в нем не объявляется тип возвращаемого значения или параметры. Аксессоры вызываются автоматически при использовании индексатора, и оба получают индекс в качестве параметра. Так, если индексатор указывается в левой части оператора присваивания, то вызывается аксессор set и устанавливается элемент, на который указывает параметр индекс. В противном случае вызывается аксессор get и возвращается значение, соответствующее параметру индекс. Кроме того, аксессор set получает неявный параметр value, содержащий значение, присваиваемое по указанному индексу.
Преимущество индексатора заключается, в частности, в том, что он позволяет полностью управлять доступом к массиву, избегая нежелательного доступа. В качестве примера рассмотрим программу, в которой создается класс FailSoftArray, реализующий массив для выявления ошибок нарушения границ массива, а следовательно, для предотвращения исключительных ситуаций, возникающих во время выполнения в связи с индексированием массива за его границами. Для этого массив инкапсулируется в качестве закрытого члена класса, а доступ к нему осуществляется только с помощью индексатора. При таком подходе исключается любая попытка получить доступ к массиву за его границами, причем эта попытка пресекается без катастрофических последствий для программы. А поскольку в классе FailSoftArray используется индексатор, то к массиву можно обращаться с помощью обычной формы записи.
<b>// Использовать индексатор для создания отказоустойчивого массива.</b>
<b>using System;</b>
<b>class FailSoftArray {</b>
<b> int[] a; // ссылка на базовый массив</b>
<b> public int Length; //открытая переменная длины массива</b>
<b> public bool ErrFlag; // обозначает результат последней операции</b>
<b> // Построить массив заданного размера, </b>
<b> public FailSoftArray(int size) { </b>
<b> a = new int [size] ;</b>
<b> Length = size;</b>
<b> }</b>
<b> // Это индексатор для класса FailSoftArray.</b>
<b> public int this[int index] {</b>
<b> // Это аксессор get. </b>
<b> get {</b>
<b> if (ok(index)) {</b>
<b> ErrFlag = false; </b>
<b> return a[index];</b>
<b> } </b>
<b> else {</b>
<b> ErrFlag = true; </b>
<b> return 0;</b>
<b> }</b>
<b> }</b>
<b> // Это аксессор set. </b>
<b> set {</b>
<b> if(ok(index)) {</b>
<b> a[index] = value;</b>
<b> ErrFlag = false;</b>
<b> }</b>
<b> else </b>
<b> ErrFlag = true;</b>
<b> }</b>
<b> }</b>
<b> // Возвратить логическое значение true, если </b>
<b> // индекс находится в установленных границах, </b>
<b> private bool ok(int index) {</b>
<b> if(index >= 0 & index < Length) return true; </b>
<b> return false;</b>
<b> }</b>
<b>}</b>
<b>// Продемонстрировать применение отказоустойчивого массива, </b>
<b>class FSDemo {</b>
<b> static void Main() {</b>
<b> FailSoftArray fs = new FailSoftArray(5); </b>
<b> int x;</b>
<b> // Выявить скрытые сбои.</b>
<b> Console.WriteLine("Скрытый сбой."); </b>
<b> for(int i=0; i < (fs.Length * 2); i++) </b>