Добавить в цитаты Настройки чтения

Страница 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 &gt;= 0 &amp; index &lt; 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(&quot;Скрытый сбой.&quot;); </b>

<b>    for(int i=0; i &lt; (fs.Length * 2); i++) </b>