Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Руководство_по_C#.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
10 Мб
Скачать
☆

5.13Индексаторы

Программисты хорошо знакомы с процессом доступа к индивидуальным элементам, содержащимся в стандартных массивах, через операцию индекса ([]). В C# имеется возможность проектировать специальные классы и структуры, которые могут быть индексированы подобно стандартному массиву, посредством определения индексатора. Это конкретное языковое средство наиболее полезно при создании специальных типов коллекций (обобщенных и необобщенных). Индексаторы могут быть одно- или многомерными.

5.13.1Одномерные индексаторы

Ниже приведена общая форма одномерного индексатора:

тип_элемента this[int индекс] {

// Аксессор для получения данных

get {

// Возврат значения, которое определяет индекс

}

// Аксессор для установки данных

set {

// Установка значения, которое определяет индекс

}}

где тип_элемента обозначает конкретный тип элемента индексатора. Следовательно, у каждого элемента, доступного с помощью индексатора, должен быть определенный тип_элемента. Этот тип соответствует типу элемента массива. Параметр индекс получает конкретный индекс элемента, к которому осуществляется доступ. Формально этот параметр совсем не обязательно должен иметь тип int, но поскольку индексаторы, как правило, применяются для индексирования массивов, то чаще всего используется целочисленный тип данного параметра.

В теле индексатора определены два аксессора (т.е. средства доступа к данным): get и set. Аксессор подобен методу, за исключением того, что в нем не объявляется тип возвращаемого значения или параметры. Аксессоры вызываются автоматически при использовании индексатора, и оба получают индекс в качестве параметра. Так, если индексатор указывается в левой части оператора присваивания, то вызывается аксессор set и устанавливается элемент, на который указывает параметр индекс. В противном случае вызывается аксессор get и возвращается значение, соответствующее индексу (индексам). Кроме того, аксессор set получает неявный параметр value, содержащий значение, присваиваемое по указанному индексу.

Давайте рассмотрим пример:

using System;

namespace ConsoleApplication1

{

class MyArr

{

int[] arr;

public int Length;

public MyArr(int Size)

{

arr = new int[Size];

Length = Size;

}

// Создаем простейший индексатор

public int this[int index]

{

set { arr[index] = value; }

get { return arr[index]; }

}

// Создаем еще один индексатор, для прикола

public String this[String index]

{ get { return "Привет, "+index; } }

}

class Program

{

static void Main()

{

MyArr arr1 = new MyArr(5);

Random ran = new Random();

// Инициализируем каждый индекс экземпляра класса arr1

for (int i = 0; i < arr1.Length; i++)

{

arr1[i] = ran.Next(1, 100);

Console.Write("{0}\t", arr1[i]);

}

Console.WriteLine("\n {0}",arr1["Педро"]);

Console.ReadKey();

}

}

}

Вывод программы:

85 32 62 52 46

Привет, Педро

В текущем классе MyArr определен индексатор, позволяющий вызывающему коду идентифицировать подэлементы с применением числовых значений. Однако надо понимать, что это не обязательное требование метода-индексатора.

Следует особо подчеркнуть, что индексатор совсем не обязательно должен оперировать массивом. Его основное назначение — предоставить пользователю функциональные возможности, аналогичные массиву.

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