将Select <>传递给方法

Bob*_*Bob 4 c# linq

我有代码

Enumerable.Range(100, 100)
          .Select(x => x / 10)
Run Code Online (Sandbox Code Playgroud)

有没有办法可以通过这条线.选择(x => x/10)到一个方法.目的是在选择发生时将结果传递给方法.我想在这里避免使用foreach.

Jon*_*eet 5

您可以编写自己的扩展方法,在每个项目通过时对其执行操作:

public static IEnumerable<T> WithAction<T>(this IEnumerable<T> source,
    Action<T> action)
{
    foreach (T item in source)
    {
        action(item);
        yield return item;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,根据您是想对原始值还是预期值进行操作,您需要写:

Enumerable.Range(100, 100)
          .Select(x => x / 10)
          .WithAction(x => Console.WriteLine(x))
Run Code Online (Sandbox Code Playgroud)

要么

Enumerable.Range(100, 100)
          .WithAction(x => Console.WriteLine(x))
          .Select(x => x / 10)
Run Code Online (Sandbox Code Playgroud)

这使它独立于Select自身.如果你需要它来使用投影,你可能会写下这样的东西:

public static IEnumerable<TResult> SelectAndAct<TSource, TResult>
    (this IEnumerable<TSource> source,
     Func<TSource, TResult> projection,
     Action<TSource, TResult> action)
{
    foreach (TSource item in source)
    {
        TResult result = projection(item);
        action(item, result);
        yield return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

Enumerable.Range(100, 100)
          .SelectAndAct(x => x / 10,
                        (x, y) => Console.WriteLine("Was: {0}; Now: {1}", x, y))
Run Code Online (Sandbox Code Playgroud)

请注意,所有这些都违反了LINQ的正常意图,即无副作用.在查询中有副作用通常不是一个好主意...但当然每个规则都有例外:)