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

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

Пример

Бери 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 ]

6 голосов
/ 21 октября 2009

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

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

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

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

3 голосов
/ 21 октября 2009

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

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

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

2 голосов
/ 21 октября 2009

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

foreach (Node n in tree)
  //...do something
...