2009-05-09 6 views
2

Est-il possible de modifier des éléments d'une collection, par exemple la liste, LinkedList, etc en utilisant quelque chose comme:Modification directe des valeurs à l'aide de LINQ?

collection.Do (action) 

qui fait quelque chose comme:

item.Value = 0 
(for each item) 

Je sais que les agents recenseurs ne donnent que la valeur, non la référence, d'où la question.

Comment le faire avec LINQ?

Répondre

6

Essayez:

void ModifyEach<T>(this IList<T> list, Func<T, T> modifier) 
{ 
    for (int n = 0; n < list.Count; n++) 
     list[n] = modifier(list[n]); 
} 

Utilisation:

List<int> x = new List<int> { 1, 3, 7 }; 

x.ModifyEach(n => n + 1); // increment each item 
+0

Merci, même chose pour IEnumerable, non? –

+0

Non, sauf si vous utilisez IEnumerable.ElementAt(), car IEnumerable n'offre pas d'accès aléatoire par défaut. Vous ne pouvez pas utiliser foreach car cela modifierait la collection. – Andy

+1

Non, il ne peut fonctionner qu'avec une interface de collection qui vous permet de modifier le contenu de la liste à une position spécifique, ce qui signifie essentiellement IList ou IDictionary. –

2

Si votre collection contient des types de référence, vous pouvez modifier ses éléments en place en utilisant une méthode d'extension, similaire à la méthode ForEach sur List<T> .

Ceci est possible car vous n'essayez pas réellement de modifier la séquence IEnumerable<T>: La collection contient des références mais vous ne modifiez que les objets référencés, pas les références elles-mêmes.

Cette technique ne fonctionnera pas pour les collections de types de valeur. Dans ce cas, vous essayez de modifier la séquence IEnumerable<T> en lecture seule, ce qui n'est pas possible.

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) 
{ 
    foreach (T item in source) 
    { 
     action(item); 
    } 
} 

// ... 

public class Example 
{ 
    public int Value { get; set; } 
} 

// ... 

Example[] examples = 
    { 
     new Example { Value = 1 }, new Example { Value = 2 }, 
     new Example { Value = 3 }, new Example { Value = 4 } 
    }; 

examples.ForEach(x => x.Value *= 2); 

// displays 2, 4, 6, 8 
foreach (Example e in examples) 
{ 
    Console.WriteLine(e.Value); 
} 
Questions connexes