2011-05-27 1 views
0

Привет У меня была проблема с каким-либо способом, который должен выполнить действие некоторого экземпляра объекта IEnumerator, пример кода показывает случай:Проблема с Linq результат

class Program 
    {   
     static void Main(string[] args) 
     { 
      string[] testArray = { "Item1", "Item2" }; 

      var query = testArray.Select((item, index) => new { index, item }); 

      Console.WriteLine("Query run 1, {0}", Environment.NewLine); 

      foreach (var obj in query) 
      { 
       Console.WriteLine("{0}", obj); 
      } 

      Console.WriteLine("Query run 2, {0}", Environment.NewLine); 

      doAction<object>(query as IEnumerator<object>, obj => Console.WriteLine(obj)); 


      Console.WriteLine("Query run 3 (same as run 1), {0}", Environment.NewLine); 

      foreach (var obj in query) 
      { 
       Console.WriteLine("{0}", obj); 
      } 

      Object tmp = Console.ReadLine(); 
     } 


     private static void doAction<T>(IEnumerator<T> enumerator, Action<T> action) 
     { 

      if (enumerator == null) 
      { 
       throw new ArgumentNullException("enumerator"); 
      } 

      if (action == null) 
      { 
       throw new ArgumentNullException("action"); 
      } 


      while (enumerator.MoveNext()) 
      { 
       action(enumerator.Current); 
      } 

     } 
    } 

Выходной сигнал:

Query run 1, 

{ index = 0, item = Item1 } 
{ index = 1, item = Item2 } 
Query run2, 

Query run 3 (same as run 1), 

{ index = 0, item = Item1 } 
{ index = 1, item = Item2 } 

Кто-нибудь знает, какой метод doAction не принимает меры?

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

Заранее спасибо.

Thnaks.

ответ

3

Да - вы не должны использовать IEnumerator<T> напрямую, только IEnumerable<T>. В основном вы видите странность в том, что компилятор C# реализует блоки итератора: есть один тип, который реализует как IEnumerable<T>, так иIEnumerator<T>. Это само по себе необычно, но это сделано по соображениям производительности. Это не то, что вы должны использовать или полагаться.

Фундаментально, подавшие IEnumerable<T> к IEnumerator<T> это плохая идея - вы не должны это сделать. Это разные интерфейсы, представляющие тонко разные идеи - разницу между «последовательностью, которая может быть перевернутой над« и »что-то, что is, итерации по последовательности».

Если вы действительно хотите использовать IEnumerator<T> в качестве типа параметра для doAction (который обычно DoAction, кстати) просто позвонить GetEnumerator() вместо:

using (var iterator = query.GetEnumerator()) 
{ 
    doAction<object>(iterator, obj => Console.WriteLine(obj)); 
} 
+0

Как кто-то может сделать эту ошибку? При обработке результатов запроса linq не используйте 'IEnumerator Interface', который« поддерживает простую итерацию по общей коллекции ». Вместо этого используйте 'IEnumerable Interface', который« выдает счетчик, который поддерживает простую итерацию по коллекции указанного типа ». –

+0

Спасибо. Не так много слов и столько информации, большой ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^