简体   繁体   English

C#继续在一行ForEach

[英]C# continue in one line ForEach

Why I can't do that ? 为什么我不能这样做? How to manipulate code ? 如何操纵代码?

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

Linq is designed for operating on sets of data - therefore, all queries must return a set. Linq设计用于操作数据集 - 因此,所有查询都必须返回一组。

You'll have to do something like this, to get a set of the required data: 你必须做这样的事情,以获得一组所需的数据:

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

Then operate on the data-set returned: 然后对返回的数据集进行操作:

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

Please, don't try doing what you tried doing, and don't do this: 请不要尝试做你尝试过的事情,不要这样做:

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

LINQ expressions should be side-effect free. LINQ表达式应该是无副作用的。 Deleting a file is surely a side effect. 删除文件肯定是副作用。 The ForEach method of List<T> is conceptually wrong (child of a pre-LINQ era). List<T>ForEach方法在概念上是错误的(LINQ之前的孩子)。 Transforming an array in a List<T> just to use the ForEach is doubly conceptually wrong. 转换List<T>的数组只是为了使用ForEach在概念上是错误的。 What I wrote at least is only "singly" conceptually wrong. 我写的至少只是“单身”在概念上是错误的。 (but it WILL work). (但它会起作用)。

Ah... and do what Dave Bish suggested! 啊......做Dave Bish建议的! foreach is the right place for side-effects! foreach是副作用的正确位置!

Just remember that his filesToDelete will be parsed lazily, so if you enumerate it twice in two foreach , the Contains check will be done twice! 请记住,他的filesToDelete将被懒惰地解析,所以如果你在两个foreach枚举两次,那么Contains检查将完成两次!

This considered, there are many powerful static methods in the Array class. 考虑到这一点, Array类中有许多强大的静态方法。 It is a pity no one uses them. 遗憾的是没有人使用它们。

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); }
System.IO.Directory.GetFiles(
    @"..\DATA\data", "*.pdf").
    ToList().
    ForEach(
        item => 
        {
            if (item.Contains("TOPRINT"))
                System.IO.File.Delete(item);
        }
    );

or 要么

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

I would add where before ForEach 我想补充的where之前ForEach

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM