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



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

 

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

public FailSoftArray(int size) {  

a = new int[size];

Length = size;

}

 

// Это индексатор типа int для массива 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;

}

}

 

/* Это еще один индексатор для массива FailSoftArray.  Он округляет свой аргумент до ближайшего целого индекса. */  

public int this[double idx] {

// Это аксессор get.  

get {

int index;

 

Округлить до ближайшего целого.

if((idx - (int) idx) < 0.5) index = (int) idx;

else index = (int) idx + 1;

 

if(ok(index)) {

ErrFlag = false;  

return a[index];

}  

else  

{

ErrFlag = true;  

return 0;

}

}

// Это аксессор set.  

set {

int index;

Округлить до ближайшего целого.

if( (idx - (int) idx) < 0.5) index = (int) idx;

else index = (int) idx + 1;

 

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);

 

// Поместить ряд значений в массив fs.  

for(int i=0; i < fs.Length; i++) fs[i] = i;

 

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

Типа int и double для обращения к массиву.

Console.WriteLine("fs[1]: " + fs[1]);

Console.WriteLine("fs[2]: " + fs[2]);

Console.WriteLine("fs[1.1]: " + fs[1.1]);

Console.WriteLine("fs[1.6]: " + fs[1.6]);

}

}

 

При выполнении этой программы получается следующий результат.

 

fs[1] : 1  

fs[2] : 2  

fs[1.1] : 1  

fs[1.6] : 2  

 

Как показывает приведенный выше результат, индексы типа double округляются до ближайшего целого значения. В частности, индекс 1.1 округляется до 1, а индекс 1.6 — до 2.

Представленный выше пример программы наглядно демонстрирует правомочность перегрузки индексаторов, но на практике она применяется нечасто. Как правило, индексаторы перегружаются для того, чтобы использовать объект определенного класса в качестве индекса, вычисляемого каким-то особым образом.

 

 

Индексаторы без базового массива

 

Следует особо подчеркнуть, что индексатор совсем не обязательно должен оперировать массивом. Его основное назначение — предоставить пользователю функциональные возможности, аналогичные массиву. В качестве примера в приведенной ниже программе демонстрируется индексатор, выполняющий роль массива только для чтения, содержащего степени числа 2 от 0 до 15. Обратите внимание на то, что в этой программе отсутствует конкретный массив. Вместо этого индексатор просто вычисляет подходящее значение для заданного индекса.

 

// Индексаторы совсем не обязательно должны оперировать отдельными массивами.

using System;

class PwrOfTwo {

/* Доступ к логическому массиву, содержащему степени числа 2 от 0 до 15. */  

 

public int this[int index] {

// Вычислить и возвратить степень числа 2.  

get {

if((index >= 0) && (index < 16))  

return pwr(index);

else  

return -1;

}

Аксессор set отсутствует.

}

 

int pwr(int p) {  

int result = 1;

for(int i=0; i < p; i++) result *= 2;

return result;

}

}

 

class UsePwrOfTwo {  

static void Main() {

PwrOfTwo pwr = new PwrOfTwo();

 

Console.Write("Первые 8 степеней числа 2: ");  

for(int i=0; i < 8; i++)

Console.Write(pwr[i] + " ");

 

Console.WriteLine();

 

Console.Write("А это некоторые ошибки: ");

Console.Write(pwr[-1] + " " + pwr[17]);

 

Console.WriteLine();

}

}

 

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

 

Первые 8 степеней числа 2: 1 2 4 8 16 32 64 128  

А это некоторые ошибки: -1 -1

 

Обратите внимание на то, что в индексатор класса PwrOfTwo включен только аксессор get, но в нем отсутствует аксессор set. Как пояснялось выше, такой индексатор служит только для чтения. Следовательно, объект класса PwrOfTwo может указываться только в правой части оператора присваивания, но не в левой его части. Например, попытка ввести следующую строку кода в приведенную выше программу не приведет к желаемому результату.

 

pwr[0] =11; //не подлежит компиляции

 

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

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

 

 

Многомерные индексаторы

 

Индексаторы можно создавать и для многомерных массивов. В качестве примера ниже приведен двумерный отказоустойчивый массив. Обратите особое внимание на объявление индексатора в этом примере.

 

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

using System;

class FailSoftArray2D {

int[,] a; // ссылка на базовый двумерный массив  


Дата добавления: 2019-02-12; просмотров: 257; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!