C# 在一行中继续 ForEach

Posted

技术标签:

【中文标题】C# 在一行中继续 ForEach【英文标题】:C# continue in one line ForEach 【发布时间】:2013-08-07 10:29:32 【问题描述】:

为什么我不能这样做?如何操作代码?

System.IO.Directory.GetFiles(@"..\DATA\data", "*.pdf").ToList().ForEach(item => item.Contains("TOPRINT") ? continue : System.IO.File.Delete(item));

【问题讨论】:

我喜欢易于阅读的代码。 @MitchWheat 我喜欢单行逻辑谜题;) 无效的表达式术语“继续” 我不喜欢编码太多;p 如果您喜欢逻辑谜题,请查看此;p 【参考方案1】:

Linq 设计用于对数据集进行操作 - 因此,所有查询都必须返回一个集。

您必须这样做,才能获得一组所需的数据:

var filesToDelete = System.IO.Directory
    .GetFiles(@"..\DATA\data", "*.pdf")
    .Where(item => !item.Contains("TOPRINT"));

然后对返回的数据集进行操作:

foreach(var file in filesToDelete)
    System.IO.File.Delete(file);

【讨论】:

您的 foreach 遍历 file,但您删除了 item :) 这是删除所有包含“TOPRINT”的项目,而原始 sn-p 的意图似乎是跳过这些文件。【参考方案2】:

请不要尝试做你尝试做的事情,也不要这样做:

System.IO.Directory.GetFiles(@"..\DATA\data", "*.pdf")
    .Where(p => p.Contains("TOPRINT"))
    .All(p =>  System.IO.File.Delete(p); return true; );

LINQ 表达式应该没有副作用。删除文件肯定是副作用。 List<T>ForEach 方法在概念上是错误的(前 LINQ 时代的子代)。在 List<T> 中转换数组只是为了使用 ForEach 在概念上是双重错误的。我至少写的只是概念上的“单一”错误。 (但它会起作用)。

啊……按照戴夫·比什的建议去做! foreach 是处理副作用的好地方!

只要记住他的filesToDelete会被懒惰地解析,所以如果你在两个foreach中枚举它两次,Contains检查将被执行两次!

考虑到这一点,Array 类中有许多强大的静态方法。可惜没人用。

var filesToDelete = System.IO.Directory.GetFiles(@"..\DATA\data", "*.pdf");
filesToDelete = Array.FindAll(filesToDelete, p => p.Contains("TOPRINT"));

Array.ForEach(filesToDelete, System.IO.File.Delete); // or
// Array.ForEach(filesToDelete, p => System.IO.File.Delete(p));            
// or, better,  foreach (var file in filesToDelete)  System.IO.File.Delete(file); 

【讨论】:

【参考方案3】:

我会在ForEach 之前添加where

System.IO.Directory.GetFiles(@"..\DATA\data", "*.pdf")
      .Where(item => !item.Contains("TOPRINT")).ToList()
      .ForEach(f=> System.IO.File.Delete(f));

【讨论】:

【参考方案4】:
System.IO.Directory.GetFiles(
    @"..\DATA\data", "*.pdf").
    ToList().
    ForEach(
        item => 
        
            if (item.Contains("TOPRINT"))
                System.IO.File.Delete(item);
        
    );

(from file in System.IO.Directory.GetFiles(@"..\DATA\data", "*.pdf")
 where file.Contains("TOPRINT")
 select file).ToList().ForEach(item => System.IO.File.Delete(item));

【讨论】:

以上是关于C# 在一行中继续 ForEach的主要内容,如果未能解决你的问题,请参考以下文章

在 Web 应用程序中使用 C# 在 asp:GridView 中复制粘贴一行

c#基础3

使用 c#、selenium 和 jquery 实现 IE 自动化 - 从动态表中随机获取

C#中按钮点击后,treeview控件怎么选中指定节点?

有没有办法在 C# 中继续异常?

在 C# 中异步等待继续后的实时 AutoResetEvent