2010-03-23 14 views
17

Aşağıdaki koddan adım adım geçerse, ReturnOne() öğesine yapılan çağrı atlanır.C# iç içe geçmiş yöntemde verim

static IEnumerable<int> OneThroughFive() 
{ 
    ReturnOne(); 
    yield return 2; 
    yield return 3; 
    yield return 4; 
    yield return 5; 
} 

static IEnumerator<int> ReturnOne() 
{ 
    yield return 1; 
} 

Sadece derleyicimin sıyırdığını varsayabilirim çünkü yaptığım şey geçerli değil. Numaralandırmamı çeşitli yöntemlere ayırma yeteneğini istiyorum. Mümkün mü?

cevap

30

Aslında ReturnOne sonucunu kullanmıyorsunuz. Yöntemi çağırıyorsunuz ve dönüş değerini görmezden geliyorsunuz. Bu, kodunuzun hiçbir zaman çalıştırılmadığını göreceğiniz anlamına gelir. Sen böyle yapabilirsin :

static IEnumerable<int> OneThroughFive() 
{ 
    foreach (int x in ReturnOne()) 
    { 
     yield x; 
    } 
    yield return 2; 
    yield return 3; 
    yield return 4; 
    yield return 5; 
} 

C# (şu anda en az :) "Tüm verim" inşa bir tür yoktur.

İçine adım atmayacağınız gerçeği, yineleme bloğu içinde bir çağrı almanız gerçeği ile ilgisi yoktur - bir yineleme bloğunun sonucu olan'u kullanarak 'u başlatana kadar , kodun hiçbiri çalışır. Bu yüzden argüman onaylamayı verimden ayırmanız gerekir. bir serbest bölüm olur ki - Derinlik C# bölüm 6 okumak, daha fazla ayrıntı için

public IEnumerator<string> ReturnSubstrings(string x) 
{ 
    if (x == null) 
    { 
     throw ArgumentNullException(); 
    } 
    return ReturnSubstringsImpl(x); 
} 

private IEnumerator<string> ReturnSubstringsImpl(string x) 
{ 
    for (int i = 0; i < x.Length; i++) 
    { 
     yield return x.Substring(i); 
    } 
} 

: Bu gibi yazmak gerekir

public IEnumerator<string> ReturnSubstrings(string x) 
{ 
    if (x == null) 
    { 
     throw ArgumentNullException(); 
    } 
    for (int i = 0; i < x.Length; i++) 
    { 
     yield return x.Substring(i); 
    } 
} 
... 
ReturnSubstring(null); // No exception thrown 

: Örneğin, bu kod düşünün ilk baskı :) Grab it here.

+0

bir şekilde kullanışlı olabilir ... – Luiscencio

+0

@Jon: Eğer ilk 'ReturnSubstrings' sonuçlarının gerçekten kullanmaya çalışırsanız ne olur? Bir "NullPointerException" veya bir "ArgumentNullException" alacak mısınız? –

+0

Bu konuyu okurken, ben aşağıya kayar ve yazar görmeden önce jon skeet bu cevap yolunu yazdığını biliyordum. @jon, gerçekten daha çok çıkmalısın. ama şimdilik, bana yeni bir şey öğrettiğin için teşekkürler. – fearofawhackplanet