将LINQ序列中的项发送到返回void的方法

a d*_*per 13 .net c# linq void

通常在我处理LINQ序列时,我想将每个项目发送到返回void的方法,避免使用foreach循环.但是,我还没有找到一种优雅的方法来做到这一点.今天,我写了以下代码:

    private StreamWriter _sw;
    private void streamToFile(List<ErrorEntry> errors)
    {
        if (_sw == null)
        {
            _sw = new StreamWriter(Path.Combine
                                    (Path.GetDirectoryName(_targetDatabasePath), "errors.txt"));
        }

        Func<ErrorEntry, bool> writeSelector = 
            (e) => { _sw.WriteLine(getTabDelimititedLine(e)); return true; };

        errors.Select(writeSelector);

        _sw.Flush();
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我编写了一个只返回true的lambda函数,我意识到Select方法将返回一个布尔序列 - 我将忽略该序列.然而,这看起来有点讽刺和下沉.有没有优雅的方法来做到这一点?或者我只是误用了LINQ?

谢谢.

SLa*_*aks 15

首先,您当前的代码将无法正常工作.
Select和大多数其他LINQ方法一样,使用延迟执行,这意味着在枚举结果之前它们实际上并没有做任何事情.

通常,在LINQ查询中不应该使用带副作用的lambda.

要回答您的问题,您应该使用foreach循环.

你正在寻找一种ForEach扩展方法; Eric Lippert解释了为什么微软没有写一个.

如果你真的想,你可以自己写一个:

public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action) {
    if (sequence == null) throw new ArgumentNullException("sequence");
    if (action == null) throw new ArgumentNullException("action");
    foreach(T item in sequence) 
        action(item);
}

//Return false to stop the loop
public static void ForEach<T>(this IEnumerable<T> sequence, Func<T, bool> action) {
    if (sequence == null) throw new ArgumentNullException("sequence");
    if (action == null) throw new ArgumentNullException("action");

    foreach(T item in sequence) 
        if (!action(item))
            return;
}
Run Code Online (Sandbox Code Playgroud)


sid*_*ews 5

常见的共识是LINQ用于查询和选择......而您使用传统的迭代方法进行循环和迭代.

我讨厌这样说,但你会使用传统的foreach循环,因为你希望你的linq查询执行,并迭代生成的IEnumerable.它有助于代码可读性,我承认LINQ会让人上瘾.您希望使用Lambdas和延迟执行来完成所有操作,但循环应留给传统的C#循环方法.这肯定有助于副作用.