2009-10-21 1 views
3

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

Пример

Возьмите 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. Почему я должен биений о кустом итерацию целое с помощью пользовательских итераций?

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

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

+0

Извините: я ответил на заданные вами вопросы, а не на ваши вопросы. Поскольку мои ответы не приветствуются, я проголосовал за их удаление. – XXXXX

+0

Извините. Я сделал общую декларацию. Не принимайте это всерьез. круто. – user193276

ответ

6

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

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

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

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

+2

И полезно, как государственная машина проверить эти ссылки: http://blogs.msdn.com/matt_pietrek/archive/2004/07/26/197242.aspx и http://bigballofmud.wordpress.com/2009/03/21/create-simple-state-machines-using-c-20-iterators/ – Audrius

+0

linq to sql не * фактически * запускает выбор N + 1 при повторном запуске (он загружает все записи при запросе первого результата) но это хороший пример. +1 –

3

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

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

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

+0

Эти примеры я взял с некоторого сайта. Так что я не понял преимущества пользовательской итерации. Я хотел составить сценарий «здесь удобная итерация». – user193276

2

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

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