2012-04-24 12 views
44

Ho iniziato a dilettarmi di recente nella metropolitana di Windows 8 e ho scoperto che uno dei miei vecchi amici sembra essere scomparso.Il metodo List <T>.ForEach() è sparito?

Io tendo ad utilizzare il metodo .ForEach() più di quello che utilizzo il tradizionale costrutto foreach() e mi sono reso conto abbastanza rapidamente che questo metodo non è disponibile. Ad esempio, questo codice non compilato nell'ambito di un app Metro:

var list = new List<string>(); 

list.ForEach(System.Diagnostics.Debug.WriteLine); 

ho cercato di vedere se riuscivo a trovare alcuna discussione su questo, ma non è stato in grado di. Sono solo ottuso, o è davvero andato?

+3

IEnumerable non ha mai avuto un metodo di estensione ForEach solo IList ha – Clueless

+0

Lei signore, è corretto. Ero prematuramente generico. Cambierò il titolo della domanda. – Robaticus

+0

Ho fatto lo stesso errore - il titolo dice IEnumerable ma l'esempio lo sta chiaramente tentando su una lista. Modifica: Titolo aggiornato :-) – yamen

risposta

42

It's indeed gone:

Lista <T> .ForEach è stato rimosso in app in stile Metro. Mentre il metodo sembra semplice, ha un certo numero di potenziali problemi quando l'elenco viene mutato dal metodo passato a ForEach. Invece si consiglia di utilizzare semplicemente un ciclo foreach.


Wes Haggard | .NET Framework Team (BCL) | http://blogs.msdn.com/b/bclteam/

Molto stranamente, però, fa la sua apparizione nel documentation, in cui nessuna parte vuol affermare che questo metodo non è supportato in .NET per le applicazioni Windows Store (precedentemente .NET per le applicazioni in stile Metro) . Forse questa è solo una svista su parte del team di documentazione.

+1

@Robaticus: puoi semplicemente aggiungere il tuo metodo di estensione per sostituirlo. Probabilmente sarebbe meglio chiamare prima ".ToList()", quindi iterarlo. Niente come ripetere una fonte mentre si tenta di mutarlo per rovinare la giornata. – Will

+1

@Will - Sono d'accordo che potrei farlo. È probabilmente una buona abitudine uscire, anche se, in particolare quando si mostrano ai nuovi programmatori LINQ come fare le cose. – Robaticus

16

Un'alternativa è quella di definire da soli, naturalmente:

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) 
{ 
    foreach(T item in enumeration) 
    { 
     action(item); 
     yield return item; 
    } 
} 

credito: LINQ equivalent of foreach for IEnumerable<T>

(Nota: non è un duplicato)

+2

Anche se questa è una pratica accettabile, basta fare attenzione a non modificare alcun requisito delle precedenti chiamate IEnumerable (come Where o OrderBy). Inoltre, se si desidera continuare a concatenare le chiamate IEnumerable, è possibile modificare il tipo restituito in 'IEnumerable ' e 'yield return item' dopo aver eseguito l'azione sull'elemento. Tuttavia, questo muterà ancora gli elementi, quindi sii consapevole che questi "effetti collaterali" potrebbero alterare l'enumerazione. – SPFiredrake

+0

Sì, ForEach è sicuramente pericoloso. Ho aggiornato la risposta per restituire "IEnumerable " al fine di consentire il concatenamento continuo, ma probabilmente questo probabilmente renderà le cose più pericolose. – yamen

18

per avere un'idea del motivo per cui potrebbe non essere più incluso, leggi questo post da qualcuno che lavora nel team C# in Microsoft: http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

Fondamentalmente, è filosofia. Le caratteristiche di "LINQ" sono fortemente ispirate al paradigma della programmazione funzionale, e l'estensione ForEach vola di fronte a questo ... incoraggia uno stile funzionale scadente.

+0

Joel: Sono stato prematuramente generico e ho cambiato il titolo in modo da riflettere l'elenco , anziché IEnumerable . – Robaticus

+8

"qualcuno che lavora nel team C# di Microsoft" Che sottile ... – BoltClock

+9

Ahhh, è solo quel ragazzo di Lippert. Che diamine sa? ;) – Robaticus

Problemi correlati