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)
常见的共识是LINQ用于查询和选择......而您使用传统的迭代方法进行循环和迭代.
我讨厌这样说,但你会使用传统的foreach循环,因为你希望你的linq查询执行,并迭代生成的IEnumerable.它有助于代码可读性,我承认LINQ会让人上瘾.您希望使用Lambdas和延迟执行来完成所有操作,但循环应留给传统的C#循环方法.这肯定有助于副作用.