代码之家  ›  专栏  ›  技术社区  ›  Mister Cook

对Linq查询结果的调用方法简洁

  •  1
  • Mister Cook  · 技术社区  · 16 年前

    我想从Linq查询中对每个对象调用MyMethod,最好的方法是什么?

    目前我正在使用:

    .Select(x => { x.MyMethod (); return x; }).ToArray();
    

    立即执行需要toArray()。

    有没有更简单的方法来写这个(没有foreach)

    谢谢

    5 回复  |  直到 16 年前
        1
  •  2
  •   Cylon Cat    16 年前

    XList已经具有您需要的方法:.ForEach()。它对每个列表成员调用一个操作。

    List<x> fooList = ....Select(x => x).ToList();
    fooList.ForEach(x => DoSomething(x));
    
        2
  •  5
  •   Mau    16 年前

    您可以指定自己的可重用扩展方法来运行 Action<> 在每个元素上,yield返回它。

    IEnumerable<T> Do(this IEnumerable<T> vals, Action<T> action) {
        foreach(T elem in vals) {
            action(elem);
            yield return elem;
        }
    }
    

    这种方法包括在 Rx library System.Interactive 命名空间。 那你就可以简单地

    myCollection.Do(x => x.MyMethod()).ToArray();
    
        3
  •  1
  •   Thomas Levesque    16 年前

    我创造了一个 Apply 扩展方法:

    public static IEnumerable<T> Apply<T>(this IEnumerable<T> source, Action<T> action)
    {
        foreach(var item in source)
        {
            action(item);
            yield return item;
        }
    }
    

    您可以按如下方式使用:

    var results = query.Apply(x => x.MyMethod()).ToArray();
    

    实际上,这和 List<T>.ForEach 方法,但它返回源的项,以便您可以继续对其应用序列运算符。

        4
  •  1
  •   msarchet    16 年前

    a for each可能是实现这一点的最简单方法,您可以编写一个扩展方法来实现for each,但是 你真的什么也得不到。

        5
  •  1
  •   Thurein    16 年前

    在我看来,你不需要调用.到转换方法,因为你只期望副作用。反应式扩展的do()方法将是一个可行的选项。

    通过使用do()方法,您有两个优势(就我而言)。

    1)延迟执行(如果需要,可以延迟立即执行)。

    2)do()方法有不同的重载,可以让您对迭代有更多的控制。 例如:do(onnext,onerror,oncompeted)重载

            var deferQuery = query.Do(x => a.MyMethod(), ex => Console.WriteLine(ex.Message), () => Console.WriteLine("Completed"));
            var immediateQuery = query.Do(x => a.MyMethod(), ex => Console.WriteLine(ex.Message), () => Console.WriteLine("Completed")).Run();