Страница 135 из 502
<b> fs[i] = i*10;</b>
<b> for(int i=0; i < (fs.Length * 2); i++) {</b>
<b> x = fs[i] ;</b>
<b> if (x != -1) Console.Write(x + " ") ;</b>
<b> }</b>
<b> Console.WriteLine();</b>
<b> //А теперь показать сбои.</b>
<b> Console.WriteLine("nСбой с уведомлением об ошибках."); </b>
<b> for(int i=0; i < (fs.Length * 2); i++) {</b>
<b> fs[i] = i * 10; </b>
<b> if(fs.ErrFlag)</b>
<b> Console.WriteLine("fs[" + i + "] вне границ");</b>
<b> }</b>
<b> for(int i=0; i < (fs.Length * 2); i++) {</b>
<b> x = fs [ i ] ;</b>
<b> if(!fs.ErrFlag) </b>
<b> Console.Write(x + " "); </b>
<b> else</b>
<b> Console.WriteLine("fs[" + i + "] вне границ");</b>
<b> }</b>
<b> }</b>
<b>}</b>
Вот к какому результату приводит выполнение этой программы.
<b>Скрытый сбой.</b>
<b>0 10 20 30 40 0 0 0 0 0</b>
<b>Сбой с уведомлением об ошибках.</b>
<b>fs[5] вне границ</b>
<b>fs[6] вне границ</b>
<b>fs[7] вне границ</b>
<b>fs[8] вне границ</b>
<b>fs[9] вне границ</b>
<b>0 10 20 30 40 fs[5] вне границ</b>
<b>fs[6] вне границ</b>
<b>fs[7] вне границ</b>
<b>fs[8] вне границ</b>
<b>fs[9] вне границ</b>
Индексатор препятствует нарушению границ массива. Внимательно проанализируем каждую часть кода индексатора. Он начинается со следующей строки.
<b>public int this[int index] {</b>
В этой строке кода объявляется индексатор, оперирующий элементами типа int. Ему передается индекс в качестве параметра index. Кроме того, индексатор объявляется открытым (public), что дает возможность использовать этот индексатор в коде за пределами его класса.
Рассмотрим следующий код аксессора get.
<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>
Аксессор get предотвращает ошибки нарушения границ массива, проверяя в первую очередь, находится ли индекс в установленных границах. Эта проверка границ выполняется в методе ok(), который возвращает логическое значение true, если индекс правильный, а иначе — логическое значение false. Так, если указанный индекс находится в установленных границах, то по этому индексу возвращается соответствующий элемент. А если индекс оказывается вне установленных границ, то никаких операций не выполняется, но в то же время не возникает никаких ошибок переполнения. В данном варианте класса FailSoftArray переменная ErrFlag содержит результат каждой операции. Ее содержимое может быть проверено после каждой операции на предмет удачного или неудачного выполнения последней. (В главе 13 будет представлен более совершенный способ обработки ошибок с помощью имеющейся в C# подсистемы обработки исключительных ситуаций, а до тех пор можно вполне обойтись установкой и проверкой признака ошибки.)
А теперь рассмотрим следующий код аксессора set, предотвращающего ошибки нарушения границ массива.
<b>set {</b>
<b> if(ok(index) ) {</b>
<b> a[index] = value;</b>
<b> ErrFlag = false;</b>
<b> }</b>
<b> else ErrFlag = true;</b>
<b>}</b>
Если параметр index метода ok() находится в установленных пределах, то соответствующему элементу массива присваивается значение, передаваемое из параметра value. В противном случае устанавливается логическое значение true переменной ErrFlag. Напомним, что value в любом аксессорном методе является неявным параметром, содержащим присваиваемое значение. Его не нужно (да и нельзя) объявлять отдельно.
Наличие обоих аксессоров, get и set, в индексаторе не является обязательным. Так, можно создать индексатор только для чтения, реализовав в нем один лишь аксессор get, или же индексатор только для записи с единственным аксессором set.