// Изменить первый объект лица с помощью индексатора.
myPeople[0] = new Person("Maggie", "Simpson", 2);
//
Получить и отобразить каждый элемент, используя индексатор.
for (int i = 0; i < myPeople.Count; i++)
{
Console.WriteLine("Person number: {0}", i);
Console.WriteLine("Name: {0} {1}",
myPeople[i].FirstName, myPeople[i].LastName);
Console.WriteLine("Age: {0}", myPeople[i].Age);
Console.WriteLine;
}
}
Индексация данных с использованием строковых значений
В текущей версии класса
PersonCollection
определен индексатор, позволяющий вызывающему коду идентифицировать элементы с применением числовых значений. Однако вы должны понимать, что это не требование индексаторного метода. Предположим, что вы предпочитаете хранить объекты
разрешают доступ к содержащимся внутри них элементам с применением ключа (такого как фамилия лица), индексатор можно было бы определить следующим образом:
using System.Collections;
using System.Collections.Generic;
namespace SimpleIndexer
{
public class PersonCollectionStringIndexer : IEnumerable
{
private Dictionary<string, Person> listPeople =
new Dictionary<string, Person>;
// Этот индексатор возвращает объект лица на основе строкового индекса.
Теперь вызывающий код способен взаимодействовать с содержащимися внутри объектами
Person
:
Console.WriteLine("***** Fun with Indexers *****\n");
PersonCollectionStringIndexer myPeopleStrings =
new PersonCollectionStringIndexer;
myPeopleStrings["Homer"] =
new Person("Homer", "Simpson", 40);
myPeopleStrings["Marge"] =
new Person("Marge", "Simpson", 38);
//
Получить объект лица Homer и вывести данные.
Person homer = myPeopleStrings["Homer"];
Console.ReadLine;
И снова, если бы обобщенный тип
Dictionary<TKey, TValue>
, напрямую, то функциональность индексаторного метода была бы получена в готовом виде без построения специального необобщенного класса, поддерживающего строковый индексатор. Тем не менее, имейте в виду, что тип данных любого индексатора будет основан на том, как поддерживающий тип коллекции позволяет вызывающему коду извлекать элементы.
Перегрузка индексаторных методов
Индексаторные методы могут быть перегружены в отдельном классе или структуре. Таким образом, если имеет смысл предоставить вызывающему коду возможность доступа к элементам с применением числового индекса или строкового значения, то в одном типе можно определить несколько индексаторов. Например, в ADO.NET (встроенный API-интерфейс .NET для доступа к базам данных) класс
DataSe
t поддерживает свойство по имени
Tables
, которое возвращает строго типизированную коллекцию
DataTableCollection
. В свою очередь тип
DataTableCollection
определяет три индексатора для получения и установки объектов
DataTable
— по порядковой позиции, по дружественному строковому имени и по строковому имени с дополнительным пространством имен:
public sealed class DataTableCollection : InternalDataCollectionBase
{
...
// Перегруженные индексаторы.
public DataTable this[int index] { get; }
public DataTable this[string name] { get; }
public DataTable this[string name, string tableNamespace] { get; }
}
Поддержка индексаторных методов вполне обычна для типов в библиотеках базовых классов. Поэтому даже если текущий проект не требует построения специальных индексаторов для классов и структур, помните о том, что многие типы уже поддерживают такой синтаксис.
Многомерные индексаторы
Допускается также создавать индексаторный метод, который принимает несколько параметров. Предположим, что есть специальная коллекция, хранящая элементы в двумерном массиве. В таком случае индексаторный метод можно определить следующим образом:
public class SomeContainer
{
private int[,] my2DintArray = new int[10, 10];
public int this[int row, int column]
{ /* получить или установить значение в двумерном массиве */ }
}
Если только вы не строите высокоспециализированный класс коллекций, то вряд ли будете особо нуждаться в создании многомерного индексатора. Пример ADO.NET еще раз демонстрирует, насколько полезной может оказаться такая конструкция. Класс
DataTable
в ADO.NET по существу представляет собой коллекцию строк и столбцов, похожую на миллиметровку или на общую структуру электронной таблицы Microsoft Excel.