【问题标题】:C# continue in one line ForEachC# 在一行中继续 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

标签: c# foreach continue


【解决方案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));
      

      【讨论】:

        猜你喜欢
        • 2010-10-11
        • 2011-12-11
        • 1970-01-01
        • 2022-08-09
        • 2011-05-15
        • 2017-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多