2010-05-26 19 views
8

Soy nuevo en expresiones lambda y busco aprovechar la sintaxis para establecer el valor de una propiedad en una colección basado en otro valor en una colecciónExpresiones lambda: establezca el valor de una propiedad en una colección de objetos según el valor de otra propiedad en la colección

Típicamente lo haría un bucle:

class Item 
{ 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

void Run() 
{ 
    Item item1 = new Item { Name = "name1" }; 
    Item item2 = new Item { Name = "name2" }; 
    Item item3 = new Item { Name = "name3" }; 

    Collection<Item> items = new Collection<Item>() { item1, item2, item3 }; 

    // This is what I want to simplify. 
    for (int i = 0; i < items.Count; i++) 
    { 
     if (items[i].Name == "name2") 
     { 
      // Set the value. 
      items[i].Value = "value2"; 
     } 
    } 
} 

Respuesta

14

LINQ es generalmente más útil para la selección de datos que para la modificación de datos. Sin embargo, se podría escribir algo como esto:

foreach(var item in items.Where(it => it.Name == "name2")) 
    item.Value = "value2"; 

Este primer elige elementos que necesitan ser modificadas y luego modifica todos ellos con un bucle imperativo estándar. Puede reemplazar el bucle foreach con ForAll método que está disponible para las listas, pero no creo que esto le da ninguna ventaja:

items.Where(it => it.Name == "name2").ToList() 
    .ForEach(it => it.Value = "value2"); 

Tenga en cuenta que es necesario agregar ToList en el medio, porque es una ForEach .NET 2.0 característica que está disponible solo para el tipo List<T> - no para todos los tipos IEnumerable<T> (como otros métodos LINQ). Si te gusta este enfoque, se puede implementar para ForEachIEnuerable<T>:

public static void ForEach<T>(this IEnumerable<T> en, Action<T> f) { 
    foreach(var a in en) f(a); 
} 

// Then you can omit the `ToList` conversion in the middle 
items.Where(it => it.Name == "name2") 
    .ForEach(it => it.Value = "value2"); 

De todos modos, preferiría foreach bucle, porque eso también deja claro que lo estás haciendo alguna mutación - y es útil para ver este hecho fácil en el código.

+0

Corrección leve: se supone que es it.value = "value2" ... –

+0

hermosa. ¿No hay forma de pasar el bucle? –

+0

@Michael Rut, el ciclo de lectura es mejor que el método ForEach, pero eso es una cuestión de opinión. Estoy de acuerdo con lo que Tomas dijo en su respuesta sobre la claridad de la acción. Sin embargo, le mostró una forma de abstraer el ciclo (aunque claramente seguirá ocurriendo un bucle, en lugar de codificarlo explícitamente o no). –

Cuestiones relacionadas