2009-10-27 22 views
28

Aşağıdaki kodu var varsayalım: someObj.GetMyStrings() döngünün her tekrarında Foreach, işlev sonuçlarında döngü yaparken nasıl çalışır?

foreach(string str in someObj.GetMyStrings()) 
{ 
    // do some stuff 
} 

denilen olacak

? yerine aşağıdakileri yapmak için daha iyi olurdu:

List<string> myStrings = someObj.GetMyStrings(); 
foreach(string str in myStrings) 
{ 
    // do some stuff 
} 

?

+20

Deneyin ve bkz. - GetMyStrings() 'de bir kesme noktası koyun ve hata ayıklayıcısının kaç kez durduğunu görün! Dispose tartışması için – AakashM

cevap

45

IEnumerator<T>; Bu durum özellikle bir - yineleyici ucuna yerleştirilmiş olduğu

using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator()) 
{ 
    while (iterator.MoveNext()) 
    { 
     Foo f = iterator.Current; 
     // Do stuff 
    } 
} 

Not: bundan sonra, MoveNext() yöntemi ve Current özellik sonuçları yineleme için kullanılır:

foreach (Foo f in GetFoos()) 
{ 
    // Do stuff 
} 

için denktir , yineleyici blok kaynakların elden için önemli mesela: yukarıdaki kodda

public IEnumerable<string> GetLines(string file) 
{ 
    using (TextReader reader = File.OpenText(file)) 
    { 
     string line; 
     while ((line = reader.ReadLine()) != null) 
     { 
      yield return line; 
     } 
    } 
} 

, gerçekten dosya wh kapalı olmak istiyorum opensubtitles2 tr Eğer yinelenen bitirirseniz ve derleyici bu işi yapmak için titizlikle IDisposable'u uygular.

+1

+1. İyi şeyler. –

+0

Yanılıyorsam düzeltin, ama C# derleyicisinin, foreach döngüsü çalışırken IEnumerable'ı düzenlemenize izin vermediğini düşünüyorum. –

+0

@ShaswatRungta: "IEnumerable'ı düzenleme" ile ne kastettiğinizi veya sorunun nasıl alakalı olduğunu bilmiyorum. –

18

Hayır .. işlev, IEnumerable'ı almak için bir kez çağrılır .. ve sonra MoveNext ve Current'a çağrı tekrarlanır.

3

GetMyStrings(), IEnumerable türünde bir nesneyi yeniden çağırır. Çalışma zamanı bununla nasıl başa çıkılacağını bilir. IEnumerable.GetEnumerator() öğesini çağırır ve daha sonra bu numaralandırma nesnesinde MoveNext() ve Current'ı çağırır.

0

"Tümü içindekiler aynı" ifadesine düştüğünüzde soruyu kapatmak için; (int x = 0; x < ProvideCeiling(); x ++) , her seferinde işlevi işlevini çağırır.

İlgili konular