2009-03-04 10 views
14

Bir iş arkadaşının yazdığı bir C# kodunda bir Listeyi yinelemek için for döngüsünü kullandı ve yorumdan çıktı, "Her şey için kullanmıyordum çünkü her zaman sırayla yinelemedim. Microsoft'un ne yapacağını kim bilir." Korkuyor.NET foreach ifadesinin, bir koleksiyonun oluşturulduğu sırayla yinelenmesi garanti edilir mi?

foreach (var item in someList)    
{ 
    System.Diagnostics.Debug.WriteLine(item); 
} 

sanırım: bunun yerine

for (int i = 0; i < someList.Count; i++)  
{ 
    System.Diagnostics.Debug.WriteLine(someList[i]); 
} 

:

var someList = new List<string>(); 

someList.Add("one"); 
someList.Add("two"); 
someList.Add("three"); 

benim iş arkadaşınız böyle bir şey kullandı: Örneğin, böyle inşa Listesini olduğunu varsayalım öğeler koleksiyona eklendiklerinden farklı bir sırayla ortaya çıkabilir. Sanırım biraz paranoyak, ama teknik olarak, belgelerin koleksiyonunun yinelenen sırasını belirtmediğini. Bir foreach ifadesinin bir dizi veya koleksiyon nesnesini en düşük sınırdan en yükseğe doğru herhangi bir sırada geçirmesi mümkün mü?

cevap

33

Sorunuz, siparişi koruyan List<T> ile ilgilidir.

foreach'in tek başına hiçbir şey yapması garanti edilmez. Sadece sayımcısı için sağlanan nesneyi, potansiyel olarak her şeyi yapabileceğini sorar.

+3

+1 Hayır, Skeet efekti daha az oy alıyor. –

+0

Skeet etkisinin üstesinden gelip gelemeyeceğimi görmek için sınama. Parmaklar geçti. –

+4

Şu anda kendi notumdan dolayı benden bir tane daha aldınız. Ben demek istediğim Skeet etkisi değil;) –

22

Bu koleksiyon bağlıdır:

  • List<T> için kampanya siparişi olmak için garantisi yoktur. (Bu sadece gösterildiği gibi Add çağrıları varsayarak. Eğer belirli yerlere listeye öğeleri eklerseniz, onlar beklediğiniz doğru pointas döndürülür.) Temelde list[0], list[1] alarak almakla aynı sipariş , list[2] vb.
  • Dictionary<TKey, TValue> için garanti verilen sipariş yoktur.
  • SortedList<TKey, TValue> (ve benzerleri) için anahtar karşılaştırma düzeninde olur - bu, türün noktasıdır.
  • Diziler her zaman öğe düzeninde ortaya çıkar.
+0

Doğru olmasına rağmen, foreach'ın SADECE olduğunu iddia ediyorum Bir koleksiyondaki tüm nesneler arasında yinelemek ve hiçbir şekilde herhangi bir siparişi garanti etmemek için. Foreach'in seçeceği sırayı belirlemek, koleksiyon uygulamasına kalmıştır. Yani foreach kullanarak garantili bir davranış yok. – DevinB

+1

@devinb Sanırım, @Jon'un söylediği şey bu. –

+2

Foreach'ın GetEnumerator'u koleksiyondan kullanması garantilidir, bu nedenle koleksiyonun yineleyicisinin siparişini biliyorsanız, foreach'dan aynı siparişi garanti edersiniz. Örneğin, bir liste üzerinde yinelemek için güvenmek tamamen mantıklıdır. –

4

Soruyu özel olarak yanıtlamak için, "foreach" ifadesini döndürür. GetEnumerator(), döndürür. Listeler için, şeyleri sonuna eklediniz. Sözlükler için, muhtemelen şeylerin atandığı bölümlerin sırasıdır.

İlgili konular