public class PersonCollectionStringIndexer : IEnumerable

  {

    private Dictionary listPeople =

        new Dictionary();

    // Этот индексатор возвращает объект лица на основе строкового индекса.

    public Person this[string name]

    {

      get => (Person)listPeople[name];

      set => listPeople[name] = value;

    }

    public void ClearPeople()

    {

      listPeople.Clear();

    }

    public int Count => listPeople.Count;

    IEnumerator IEnumerable.GetEnumerator() => listPeople.GetEnumerator();

  }

}

Теперь вызывающий код способен взаимодействовать с содержащимися внутри объектами 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, напрямую, то функциональность индексаторного метода была бы получена в готовом виде без построения специального необобщенного класса, поддерживающего строковый индексатор. Тем не менее, имейте в виду, что тип данных любого индексатора будет основан на том, как поддерживающий тип коллекции позволяет вызывающему коду извлекать элементы.

<p id="AutBody_Root407">Перегрузка индексаторных методов</p>

Индексаторные методы могут быть перегружены в отдельном классе или структуре. Таким образом, если имеет смысл предоставить вызывающему коду возможность доступа к элементам с применением числового индекса или строкового значения, то в одном типе можно определить несколько индексаторов. Например, в ADO.NET (встроенный API-интерфейс .NET для доступа к базам данных) класс DataSet поддерживает свойство по имени 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; }

}

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

<p id="AutBody_Root408">Многомерные индексаторы</p>

Допускается также создавать индексаторный метод, который принимает несколько параметров. Предположим, что есть специальная коллекция, хранящая элементы в двумерном массиве. В таком случае индексаторный метод можно определить следующим образом:

public class SomeContainer

{

  private int[,] my2DintArray = new int[10, 10];

  public int this[int row, int column]

  {  /* получить или установить значение в двумерном массиве */  }

}

Если только вы не строите высокоспециализированный класс коллекций, то вряд ли будете особо нуждаться в создании многомерного индексатора. Пример ADO.NET еще раз демонстрирует, насколько полезной может оказаться такая конструкция. Класс DataTable в ADO.NET по существу представляет собой коллекцию строк и столбцов, похожую на миллиметровку или на общую структуру электронной таблицы Microsoft Excel.

Перейти на страницу:

Похожие книги