2013-02-12 3 views
1

Может ли кто-нибудь помочь мне понять, почему вывод двух for loops ниже производит разные выходы?Несоответствия между выводом словаря <int, string> и Queue <KeyValuePair <int, string>> in C#

Они, на мой взгляд такие же, однако оригинального Dictionary объекта for loop выводит все 9 своих членов, но и Queue объекты for loop выводит только первые 5.

void test() 
{ 
     Dictionary<int, string> d = new Dictionary<int, string>(); 

     d.Add(0, "http://example.com/1.html"); 
     d.Add(1, "http://example.com/2.html"); 
     d.Add(2, "http://example.com/3.html"); 
     d.Add(3, "http://example.com/4.html"); 
     d.Add(4, "http://example.com/5.html"); 
     d.Add(5, "http://example.com/6.html"); 
     d.Add(6, "http://example.com/7.html"); 
     d.Add(7, "http://example.com/8.html"); 
     d.Add(8, "http://example.com/9.html"); 

     Queue<KeyValuePair<int, string>> requestQueue = new Queue<KeyValuePair<int, string>>(); 

     // build queue 
     foreach (KeyValuePair<int, string> dictionaryListItem in d) 
     { 
      requestQueue.Enqueue(dictionaryListItem); 
      Console.WriteLine(dictionaryListItem.Value); 
     } 

     Console.WriteLine("   "); 

     for (int i = 0; i < requestQueue.Count; i++) 
     { 
      Console.WriteLine(requestQueue.Peek().Value); 
      requestQueue.Dequeue(); 
     } 
} 

ответ

6

Вы должны сохранить подсчитывать до цикл:

var count = requestQueue.Count; 
for (int i = 0; i < count; i++) 
{ 
    Console.WriteLine(requestQueue.Peek().Value); 
    requestQueue.Dequeue(); 
} 

причина заключается в том, что оно вычисляется на каждой итерации цикла для:

В начале первой итерации requestQueue.Count - 9, i - 0.
2-я итерация: requestQueue.Count is 8, i является 1.
3-я итерация: requestQueue.Count is 7, i является 2.
4-я итерация: requestQueue.Count - 6, i - 3.
5-я итерация: requestQueue.Count - 5, i - 4.
6-я итерация: requestQueue.Count is 4, i is 5. -> Выход из цикла.

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

+0

точка сверху. Благодарю. зачем это нужно? думал бы requestQueue.Count проведет правильный val? –

+0

@RodgersandHammertime: он сохраняет правильное значение. Повторите мой ответ. Вы понимаете, что 'Dequeue' удаляет элемент из очереди? –

+0

Спасибо, понимаете сейчас :) –

3

Вы, вероятно, хотите использовать эту while-loop вместо которой является более значимой здесь:

while (requestQueue.Count > 0) 
{ 
    Console.WriteLine(requestQueue.Peek().Value); 
    requestQueue.Dequeue(); 
} 

Проблемы с for-loop что Queue.Dequeue удаляет первый элемент, который также уменьшает Count свойства. Вот почему он останавливается «на части».

Переменная контура i все еще увеличивается, тогда как Count уменьшается.

+0

Спасибо, теперь имеет смысл. –

+0

@Rodgers и Hammertime: если по какой-то причине вам нужен индекс, вы также можете изменить for-loop на 'for (int i = 0; requestQueue.Count> 0; i ++)' –

1

Поскольку вы меняете количество элементов в requestQueue каждый раз, когда вы вызываете requestQueue.Dequeue(). Вместо этого сохраните значение count в локальном и loop с этим локальным как верхний предел.

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