Using the magic of LINQ - How to call a delegate for each criteria that matches?
I wanna do something like this:
List<string> list = new List<string>();
... put some data in it ...
list.CallAc开发者_C百科tionForEachMatch(x=>x.StartsWith("a"), ()=> Console.WriteLine(x + " matches!"););
Syntax: CallActionForEachMatch(Criteria, Action)
How is this possible? :)
I wouldn't; I'd just use:
foreach(var item in list.Where(x=>x.StartsWith("a"))) {
Console.WriteLine(item + " matches!");
}
But you could use:
list.FindAll(x=>x.StartsWith("a"))
.ForEach(item=>Console.WriteLine(item + " matches!"));
list.FindAll(x=>x.StartsWith("a"))
.ForEach(x => Console.WriteLine(x + " matches!"));
Or you can write your own CallActionForEachMatch extension:
public static void CallActionForEachMatch<T>(this IEnumerable<T> values, Func<T, bool> pred, Action<T> act)
{
foreach (var value in values.Where(pred))
{
act(value);
}
}
Write extension methods:
static class IEnumerableForEachExtensions {
public static void ForEachMatch<T>(this IEnumerable<T> items,
Predicate<T> predicate,
Action<T> action
) {
items.Where(x => predicate(x)).ForEach(action);
}
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action) {
foreach(T item in items) {
action(item);
}
}
}
Usage:
// list is List<string>
list.ForEachMatch(s => s.StartsWith("a"), s => Console.WriteLine(s));
Note this is fully general as it will eat any IEnumerable<T>
. Note that there are some that would consider this an abuse of LINQ because of the explicit side effects.
An extension method something like this:
static public void CallActionForEachMatch(this List<T> list, Func<T, bool> criteria, Action<T> action)
{
list.Where(criteria).ToList().ForEach(action);
}
精彩评论