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


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



ЗНАЕТЕ ЛИ ВЫ?

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

10.1.2 Перегрузка индексаторов

Индексатор может быть перегружен. В этом случае для выполнения выбирается тот вариант индексатора, в котором точнее соблюдается соответствие его параметра и аргумента, указываемого в качестве индекса. Ниже приведен пример программы, в ко­торой индексатор массива класса FailSoftArray перегружается для индексов типа double. При этом индексатор типа double округляет свой индекс до ближайшего целого значения.

Листинг 10.2

// Перегрузить индексатор массива класса FailSoftArray.

 

using System; 

 

class FailSoftArray

{  

int[] a; // Ссылка на базовый массив  

 

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

 

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

 

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

public FailSoftArray(int size) { 

a = new int[size]; 

Length = size;  

 

// Этот индексатор типа int для массива FailSoftArray 

public int this[int index] { 

// This is the get accessor. 

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; 

 

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

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. Обратите внимание на то, что в этой программе отсутствует конкретный массив. Вместо этого индексатор просто вычисляет подходящее значение для заданного индекса.

Листинг 10.3

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

// массивами.

 

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.



Поделиться:


Последнее изменение этой страницы: 2024-07-06; просмотров: 47; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.196 (0.006 с.)