开发者

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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜