- •10 Индексаторы и свойства
- •10.1 Индексаторы
- •10.1.1 Создание одномерных индексаторов
- •10.1.2 Перегрузка индексаторов
- •10.1.3 Индексаторы без базового массива
- •10.1.4 Многомерные индексаторы
- •10.2 Свойства
- •10.2.1 Автоматически реализуемые свойства
- •10.2.2 Применение инициализаторов объектов в свойствах
- •10.2.3 Ограничения, присущие свойствам
- •10.3 Применение модификаторов доступа в аксессорах
- •10.4 Применение индексаторов и свойств
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.
Представленный выше пример программы наглядно демонстрирует правомочность перегрузки индексаторов, но на практике она применяется нечасто. Как правило, индексаторы перегружаются для того, чтобы использовать объект определенного класса в качестве индекса, вычисляемого каким-то особым образом.
