Практическое руководство. Доступ к классу коллекции с помощью оператора foreach (Руководство по программированию в C#)
В следующем примере кода показано, как записать неуниверсальный класс коллекции, который можно использовать с оператором foreach. В этом примере определяется класс строкового лексического анализатора.
Примечание
Этот пример представляет рекомендованный способ, только если использование универсального класса коллекции невозможно.Для примера реализации типобезопасного универсального класса коллекции, поддерживающего тип IEnumerable<T>, см. раздел Практическое руководство. Создание блока итератора для общего списка (Руководство по программированию на C#).
В примере следующий сегмент кода использует класс Tokens для разделения предложения "Это предложение-образец." на токены с помощью разделителей " " и "-". Затем код отображает эти токены с помощью оператора foreach.
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
// Display the tokens.
foreach (string item in f)
{
System.Console.WriteLine(item);
}
Пример
По сути, класс Tokens использует массив для хранения токенов. Поскольку массивы реализуют типы IEnumerator и IEnumerable, пример кода может использовать методы перечисления массивов (GetEnumerator, MoveNext, Reset и Current) вместо определения их в классе Tokens. Определения методов содержатся в примере для уточнения способа их определения и предназначения каждого из них.
using System.Collections;
// Declare the Tokens class. The class implements the IEnumerable interface.
public class Tokens : IEnumerable
{
private string[] elements;
Tokens(string source, char[] delimiters)
{
// The constructor parses the string argument into tokens.
elements = source.Split(delimiters);
}
// The IEnumerable interface requires implementation of method GetEnumerator.
public IEnumerator GetEnumerator()
{
return new TokenEnumerator(this);
}
// Declare an inner class that implements the IEnumerator interface.
private class TokenEnumerator : IEnumerator
{
private int position = -1;
private Tokens t;
public TokenEnumerator(Tokens t)
{
this.t = t;
}
// The IEnumerator interface requires a MoveNext method.
public bool MoveNext()
{
if (position < t.elements.Length - 1)
{
position++;
return true;
}
else
{
return false;
}
}
// The IEnumerator interface requires a Reset method.
public void Reset()
{
position = -1;
}
// The IEnumerator interface requires a Current method.
public object Current
{
get
{
return t.elements[position];
}
}
}
// Test the Tokens class.
static void Main()
{
// Create a Tokens instance.
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
// Display the tokens.
foreach (string item in f)
{
System.Console.WriteLine(item);
}
}
}
/* Output:
This
is
a
sample
sentence.
*/
В языке C# классу коллекции необязательно реализовывать IEnumerable и IEnumerator для совместимости с foreach. Если в классе содержатся обязательные члены GetEnumerator, MoveNext, Reset и Current, он будет работать с оператором foreach. Пропуск интерфейсов имеет преимущество, поскольку позволяет определить тип возврата для Current, который более специфичен, чем тип Object. Это повышает типобезопасность.
Например, измените следующие строки в предыдущем примере.
// Change the Tokens class so that it no longer implements IEnumerable.
public class Tokens
{
// . . .
// Change the return type for the GetEnumerator method.
public TokenEnumerator GetEnumerator()
{ }
// Change TokenEnumerator so that it no longer implements IEnumerator.
public class TokenEnumerator
{
// . . .
// Change the return type of method Current to string.
public string Current
{ }
}
}
Поскольку Current возвращает строку, компилятор может определить, когда используется несовместимый тип в операторе foreach, как показано в следующем примере.
// Error: Cannot convert type string to int.
foreach (int item in f)
Недостатком пропуска типов IEnumerable и IEnumerator является то, что класс коллекции больше не может взаимодействовать с операторами foreach или эквивалентными операторами из других языков среды CLR.
См. также
Ссылки
Массивы (Руководство по программированию на C#)
Классы коллекций (Руководство по программированию в C#)
Основные понятия
Руководство по программированию на C#
Другие ресурсы
Журнал изменений
Дата |
Журнал |
Причина |
---|---|---|
Март 2011 |
Отредактировано для повышения ясности. |
Улучшение информации. |