2008-12-04 27 views
31

En primer lugar, sé que hay métodos fuera de la clase genérica List<> que ya están en el marco iterar sobre List<>.Sintaxis de C# - Ejemplo de una expresión de Lambda - ForEach() sobre la lista genérica

Pero como ejemplo, ¿cuál es la sintaxis correcta para escribir un método ForEach para iterar sobre cada objeto de un List<>, y hacer un Console.WriteLine(object.ToString()) en cada objeto. Algo que toma el List<> como primer argumento y la expresión lambda como el segundo argumento.

La mayoría de los ejemplos que he visto se hacen como métodos de extensión o involucran LINQ. Estoy buscando un ejemplo de método simple.

Respuesta

50
public void Each<T>(IEnumerable<T> items, Action<T> action) 
{ 
    foreach (var item in items) 
     action(item); 
} 

... y lo llaman así:

Each(myList, i => Console.WriteLine(i)); 
+0

fresca. Ahora, ¿dónde entra en juego la sintaxis Func <> que he visto? – BuddyJoe

+11

Los delegados de Func <> son delegados genéricos para los métodos con valores devueltos. Los delegados Action <> son delegados genéricos para los métodos SIN valores devueltos. Esa es la única diferencia. – TheSoftwareJedi

+1

por lo tanto, en su caso, no necesita devolver algo (desde console.writeline - por lo que Acción es suficiente. – TheSoftwareJedi

26

Lo anterior también se podría escribir con menos código como:

new List<SomeType>(items).ForEach(
    i => Console.WriteLine(i) 
); 

Esto crea una lista genérica y lo llena con el IEnumerable y luego llama a la lista de objetos ForEach.

+0

La pregunta que se le preguntó cómo escribir el método (no cómo llamarlo), y especificó que él no quería usar LINQ o métodos de extensión. – StriplingWarrior

+0

Esto es conveniente, pero ¿no es la sobrecarga de crear una nueva lista (lo que implica iterar sobre los elementos al menos una vez más) por lo general no vale la pena? – dumdum

+0

Muy útil, gracias. – Bryan

0

Puede recorrer cada cadena en la lista e incluso puede buscar en el genérico completo utilizando una sola instrucción que facilita la búsqueda.

public static void main(string[] args) 
{ 
List names = new List(); 

names.Add(“Saurabh”); 
names.Add("Garima"); 
names.Add(“Vivek”); 
names.Add(“Sandeep”); 

string stringResult = names.Find(name => name.Equals(“Garima”)); 
} 
22

¿Es esto lo que estás pidiendo?

int[] numbers = { 1, 2, 3 }; 
numbers.ToList().ForEach(n => Console.WriteLine(n)); 
+0

sí. esto a mano y lo he usado. +1. En el momento en que hice la pregunta, creo que estaba tratando de entender la sintaxis básica de C# lambda cuando se usa con genéricos. – BuddyJoe

+0

Bien, pero tenemos que considerar que ToList() es una operación O (n) –

9
public static void Each<T>(this IEnumerable<T> items, Action<T> action) { 
foreach (var item in items) { 
    action(item); 
} } 

... y lo llaman así:

myList.Each(x => { x.Enabled = false; }); 
+1

Una ventaja para mostrar la forma de hacer varias operaciones en Cada. – Amir978

1

quiere poner por ahí que no hay mucho que preocuparse de si alguien da una respuesta como un método de extensión debido a una extensión método es solo una forma genial de llamar a un método de instancia. Entiendo que quieres la respuesta sin usar un método de extensión. Independientemente de si el método se define como estático, instancia o extensión, el resultado es el mismo.

El siguiente código utiliza el código de la respuesta aceptada para definir un método de extensión y un método de instancia y crea una prueba de unidad para mostrar que la salida es la misma.

public static class Extensions 
{ 
    public static void Each<T>(this IEnumerable<T> items, Action<T> action) 
    { 
     foreach (var item in items) 
     { 
      action(item); 
     } 
    } 
} 

[TestFixture] 
public class ForEachTests 
{ 
    public void Each<T>(IEnumerable<T> items, Action<T> action) 
    { 
     foreach (var item in items) 
     { 
      action(item); 
     } 
    } 

    private string _extensionOutput; 

    private void SaveExtensionOutput(string value) 
    { 
     _extensionOutput += value; 
    } 

    private string _instanceOutput; 

    private void SaveInstanceOutput(string value) 
    { 
     _instanceOutput += value; 
    } 

    [Test] 
    public void Test1() 
    { 
     string[] teams = new string[] {"cowboys", "falcons", "browns", "chargers", "rams", "seahawks", "lions", "heat", "blackhawks", "penguins", "pirates"}; 

     Each(teams, SaveInstanceOutput); 

     teams.Each(SaveExtensionOutput); 

     Assert.AreEqual(_extensionOutput, _instanceOutput); 
    } 
} 

Literalmente, lo único que tiene que hacer para convertir un método de extensión a un método de instancia es quitar el modificador static y el primer parámetro del método.

Este método

public static void Each<T>(this IEnumerable<T> items, Action<T> action) 
{ 
    foreach (var item in items) 
    { 
     action(item); 
    } 
} 

convierte

public void Each<T>(Action<T> action) 
{ 
    foreach (var item in items) 
    { 
     action(item); 
    } 
} 
Cuestiones relacionadas