Ответ 1
Обычно вы используете индексатор, если класс представляет список, коллекцию или массив объектов. В вашем случае вы можете предоставить индексирующее средство для предоставления доступа на основе индексов учащимся-преподавателям.
Я хотел бы использовать индексаторы больше, но я не уверен, когда их использовать. Все, что я нашел в Интернете, - это примеры, которые используют классы типа MyClass
и IndexerClass
.
Как насчет в школьной системе, где есть ученики и учителя, и у каждого Учителя есть список учеников, за которыми они отвечают - любая потребность в индексаторах в этом сценарии? Для простоты: каждый ученик может принадлежать только одному Учителю.
Обычно вы используете индексатор, если класс представляет список, коллекцию или массив объектов. В вашем случае вы можете предоставить индексирующее средство для предоставления доступа на основе индексов учащимся-преподавателям.
Вот видео, которое я создал http://www.youtube.com/watch?v=HdtEQqu0yOY, а ниже - подробное объяснение о том же.
Индексаторы помогают получить доступ к содержащейся коллекции в классе с использованием упрощенного интерфейса. Его синтаксический сахар.
Например, скажем, у вас есть класс клиентов с коллекцией адресов внутри него. Теперь позвольте сказать, что мы хотели бы получить выборку из коллекции "Pincode" и "PhoneNumber". Таким образом, логичным шагом будет то, что вы идете и создаете две перегруженные функции, которые выбираются с помощью "PhoneNumber", а другой - "PinCode". Вы можете видеть в приведенном ниже коде, у нас есть две функции.
Customer Customers = new Customer();
Customers.getAddress(1001);
Customers.getAddress("9090");
Если вы используете индексатор, вы можете упростить приведенный выше код, как показано в приведенном ниже коде.
Customer Customers = new Customer();
Address o = Customers[10001];
o = Customers["4320948"];
Приветствия.
Случайный порядок доступа
Вы должны использовать перечислитель, если ваши данные обычно доступны последовательно.
Индексатор, с другой стороны, полезен для прямого доступа к определенному элементу, без определенного порядка.
Это, конечно, предполагает, что вы знаете индекс элемента, который вы хотите. Комбинации, например, всегда поддерживают два значения: строка, показанная пользователю, и идентификатор, который принадлежит ей. Вы можете использовать идентификатор из выбранного элемента в combobox для прямого доступа к индексу вашей коллекции вместо поиска в коллекции.
Хорошая вещь об индексаторах на С# заключается в том, что вы можете перегружать их, чтобы вы могли обращаться к элементам с помощью разных типов ключей.
Indexer - это высокоспециализированное свойство, которое позволяет индексировать экземпляры класса (или структуры) точно так же, как массив (свойства могут быть статическими, но индексаторы не могут).
Зачем использовать индексы:
- вместо новой структуры данных сам класс является структурой данных.
- упрощенный синтаксис - синтаксический сахар
Когда использовать:
- если вашему классу нужен список (/массив) его экземпляров (пример 1)
- если ваш класс представляет список (/массив) значений, непосредственно связанных с вашим классом (пример 2)
Пример 1:
public Class Person{
public string Name{get; set;}
private Person[] _backingStore;
public Person this[int index]
{
get{
return _backingStore[index];
}
set{
_backingStore[index] = value;
}
}
}
Person p = new Person();
p[0] = new Person(){Name = "Hassan"};
p[1] = new Person(){Name = "John Skeet"};
Пример 2:
class TempratureRecord{
private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F, 61.3F};
public int Length{
get { return temps.Length; }
}
public float this[int index]
{
get{
return temps[index];
}
set{
temps[index] = value;
}
}
}
Простой ответ (как указано выше), когда класс представляет/содержит набор элементов, индексщик возвращает элементы коллекции.
public Student this[int index] { ..
В более сложном случае вы можете создать поведение по умолчанию с классом и сделать его похожим на делегата, особенно когда класс представляет собой сопоставление или процесс. Например, класс, который вычисляет скорость охлаждения пива в холодильнике:
Вместо ввода
temperature = coorsLight.CalculateFutureTemperature(time);
вы можете смириться с этим
temperature = coorsLight[time];
если ожидаемое поведение (и намерение) класса должно вернуть значение.
Указатель - это средство выбора элемента из совокупности, такого как массив или коллекция. Хотя я согласен частично с Яном Дэвисом, я считаю, что индексаторы представляют собой нечто большее, чем публичный API-интерфейс.
Индексаторы являются основным средством доступа к массивам и большинству основных классов, представляющих коллекции в .NET-интегрированных индексаторах BCL, по-видимому, для обеспечения общего опыта при работе с типами, которые объединяют другие типы.
Поскольку индексы являются стандартной частью интерфейса для многих типов коллекций BCL, и поскольку эти типы сильно используются, поскольку разработчики изучают .NET как платформу, разумно предположить, что создается ожидание, которое может можно получить доступ с помощью какого-либо индексатора.
Если ваш тип интерфейса соответствует ожиданиям разработчиков, то этот тип становится проще в использовании, потому что разработчику не нужно думать. Это верно, независимо от того, являются ли разработчики внутренними для вашей организации или там в дикой природе.
Конечно, есть ситуации, когда индексатор просто не имеет смысла, и если это случай, то не реализуйте индексатор.
ИМХО, индексы, вероятно, лучше всего, если вы пытаетесь создать упакованный API - это не стоит усилий для запуска бизнес-объекта mill.
И если вы создадите специализированную коллекцию, я бы категоризировал это как создание вашего упакованного API - даже если вы сохраните все это в одном модуле.
Использование индексатора в вашей ситуации было бы классом TeachersClass, который бы инкапсулировал студентов (коллекцию) и текущего учителя. Хотя вы можете сделать то же самое, разоблачив список учеников, но он показывает вам пример.
Вот пример кода:
public class TeachersClass
{
private List<Student> _students;
public TeachersClass(Teacher currentTeacher, List<Student> students)
{
CurrentTeacher = currentTeacher;
_students = students;
}
public Teacher CurrentTeacher { get; set; }
public Student this[int studentID]
{
get
{
return (from s in _students
where s.Id = studentID
select s).First();
}
}
}
Индексаторы позволяют индексировать экземпляры класса или структуры как массивы. Индексаторы напоминают свойства, за исключением того, что их аксессоры принимают параметры.
Индексаторы позволяют индексировать объекты аналогично массивам.
// C#: INDEXER
using System;
using System.Collections;
class MyClass
{
private string []data = new string[5];
public string this [int index]
{
get
{
return data[index];
}
set
{
data[index] = value;
}
}
}
class MyClient
{
public static void Main()
{
MyClass mc = new MyClass();
mc[0] = "Rajesh";
mc[1] = "A3-126";
mc[2] = "Snehadara";
mc[3] = "Irla";
mc[4] = "Mumbai";
Console.WriteLine("{0},{1},{2},{3},{4}",mc[0],mc[1],mc[2],mc[3],mc[4]);
}
}
Я помню, что было это время, когда у меня была длинная внутри класса, а некоторые цифры этого конкретного долгое время имели в виду что-то (например, если третья цифра была 3, это означало, что на диаграмме был определенный тип кодировки, ужасный система, которую я знаю, но я ее не изобретал)
Итак, я сделал что-то подобное, чтобы вернуть x-цифру числа:
protected int this[int index]
{
get
{
int tempN = Number;
if (index > 0)
{
tempN /= index * 10;
}
return tempN % 10;
}
}
Он был защищен, потому что другой метод использовал его, поэтому он был своего рода помощником. Конечно, простой GetDigit (int a) был бы одним и тем же (и более самоочевидным), но в то время, когда я думал, что это был один из немногих раз, когда я думал, что использование индексатора имеет смысл. Не использовали их с = (.