Когда можно использовать пользовательские перечисления / коллекции?

Я опускаю эту строку после посещения разных веб-сайтов, чтобы попытаться понять пример использования пользовательского перечисления в реальном времени. У меня есть примеры. Но они приводят меня в замешательство.

пример

Взять 1

class NumberArray
{
    public int[] scores;

    public NumberArray()
    {
    }

    public NumberArray(int[] scores)
    {
        this.scores = scores;
    }

    public int[] Scores
    {
        get {return scores;}
    }

}

Взять 2

public class Enumerator : IEnumerator
{
    int[] scores;
    int cur;
    public Enumerator(int[] scores)
    {
        this.scores = scores;
        cur = -1;
    }
    public Object Current
    {
        get {
            return scores[cur];
        }
    }

    public void Reset()
    {
        cur = -1;
    }

    public bool MoveNext()
    {
        cur++;
        if (cur < scores.Length)
            return true;
        else return false;
    }
}

public class Enumerable : IEnumerable
{
    int[] numbers;

    public void GetNumbersForEnumeration(int[] values)
    {
        numbers = values;
        for (int i = 0; i < values.Length; i++)
            numbers[i] = values[i];
    }

    public IEnumerator GetEnumerator()
    {
        return new Enumerator(numbers);
    }
}

Главный

static void Main()
{
    int[] arr = new int[] { 1, 2, 3, 4, 5 };
    NumberArray num = new NumberArray(arr);
    foreach(int val in num.Scores)
    {
        Console.WriteLine(val);
    }

    Enumerable en = new Enumerable();
    en.GetNumbersForEnumeration(arr);

    foreach (int i in en)
    {
        Console.WriteLine(i);
    }
    Console.ReadKey(true);
}

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

Возможно, я пропустил пользовательскую потребность в итерации в реальном времени. Можете ли вы объяснить мне задачу, которую я не могу сделать с существующим средством итерации? (Я только что закончил учебу, так что приведите простой пример, чтобы я мог его правильно понять).

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

3 ответа

Решение

Пользовательские итераторы полезны, когда ресурсы, которые вы перебираете, предварительно не загружаются в память, а скорее получают по мере необходимости в каждой итерации. Например, в LINQ to SQL, когда вы делаете что-то вроде:

foreach(var employee in dataContext.Employees) {
    // Process employee
}

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

Смотрите здесь для реального примера: перечислить строки в файле. Здесь каждая строка читается из файла на каждой итерации foreach петля. (как примечание, .NET Framework 4 предлагает такую ​​же встроенную функциональность).

Если честно, я не совсем уверен в том, что вы спрашиваете, но если вы беспокоитесь о разнице между возвратом массива (как в дубле 1) и возвратом итератора (дубль 2), вот мой ответ.

Существует большая разница между возвратом массива и возвратом итератора. Возврат массива означает возврат внутреннего состояния (если вы не сделаете копию как часть возврата, но это дорого). Если вы возвращаете итератор, вы просто возвращаете абстракцию, которая позволит вызывающим абонентам выполнять итерацию состояния. Это также означает, что вы можете выполнять ленивую оценку, если вам нужно (что вы, очевидно, не можете сделать, если возвращаете массив).

Кроме того, с поддержкой итераторов в C# 2, на самом деле нет оснований для реализации IEnumerable вручную. Пожалуйста, посмотрите этот вопрос для дополнительной информации. Может ли кто-нибудь демистифицировать ключевое слово yield?

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

foreach (Node n in tree)
  //...do something
Другие вопросы по тегам