2016-03-09 26 views
5

È possibile utilizzare yield in linea con il metodo ForEach?foreach vs ForEach utilizzando yield

private static IEnumerable<string> DoStuff(string Input) 
{ 
    List<string> sResult = GetData(Input); 
    sResult.ForEach(x => DoStuff(x)); 

    //does not work 
    sResult.ForEach(item => yield return item;); 

    //does work 
    foreach(string item in sResult) yield return item; 
} 

in caso contrario, c'è un motivo per cui non funziona?

+1

dare un'occhiata a: http://stackoverflow.com/q/1217729/1859022 – user1859022

+4

In primo luogo, * Perché * utilizzare questa sintassi anziché '.Select (x => DoStuff (x))'? Second, 'ForEach' non restituisce un risultato, quindi provare a restituire qualcosa con' return' o 'yield' non è valido –

+0

@PanagiotisKanavos' Select' non funziona combinato con un approccio ricorsivo – fubo

risposta

7

Perché, come si può vedere here una funzione lambda è compilato per un metodo separato:

questo:

x => DoStuff(x) 

viene convertito in

internal void <DoStuff>b__1_0(string x) 
{ 
    C.DoStuff(x); 
} 

Questo metodo separato non è un IEnumerable<> quindi chiaramente non supporta la parola chiave yield.

Così, per esempio questo:

item => yield return item; 

sarebbe convertito:

internal void <DoStuff>b__1_0(string item) 
{ 
    yield return item; 
} 

che ha il yield ma non è IEnumerable<string>.

9

No, List<T>.ForEach non può essere utilizzato per questo.

prende un delegato Action<T>.

Action<T> "Incapsula un metodo che ha un singolo parametro e non restituisce un valore."

Quindi la lambda che hai creato non può restituire nulla se deve "adattarsi" in un Action<T>.