Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

using System.Collections.Generic;

static void UseGenericListOfPeople

{

List<Person> myPeople = new List<Person>;

myPeople.Add(new Person("Lisa", "Simpson", 9));

myPeople.Add(new Person("Bart", "Simpson", 7));

// Изменить первый объект лица с помощью индексатора.

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
определен индексатор, позволяющий вызывающему коду идентифицировать элементы с применением числовых значений. Однако вы должны понимать, что это не требование индексаторного метода. Предположим, что вы предпочитаете хранить объекты
Person
, используя тип
System.Collections.Generic.Dictionary<TKey,TValue>
, а не
ArrayList
. Поскольку типы
Dictionary
разрешают доступ к содержащимся внутри них элементам с применением ключа (такого как фамилия лица), индексатор можно было бы определить следующим образом:

using System.Collections;

using System.Collections.Generic;

namespace SimpleIndexer

{

public class PersonCollectionStringIndexer : IEnumerable

{

private Dictionary<string, Person> listPeople =

new Dictionary<string, Person>;

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

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<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.

Поделиться с друзьями: