C# LINQ中IEnumerable/List的组合操作?

C# LINQ中IEnumerable/List的组合操作?,c#,linq,C#,Linq,我想从符合特定条件的目录中删除每个文件,但我也希望从列表(或IEnumerable)中删除这些项(因为我希望以后使用该列表,并且不希望其中的任何项在文件系统中不再存在!) 一种简单的方法是将符合某个条件的每个项目收集到一个列表中,然后在临时列表中循环,并从原始列表中删除文件和listitem。但我希望看到一个解决方案,在一个步骤中完成这两项任务,而无需首先创建过滤的临时列表 // non-sense code example lstFiles.ForEach(x => x.Creation

我想从符合特定条件的目录中删除每个文件,但我也希望从列表(或IEnumerable)中删除这些项(因为我希望以后使用该列表,并且不希望其中的任何项在文件系统中不再存在!)

一种简单的方法是将符合某个条件的每个项目收集到一个列表中,然后在临时列表中循环,并从原始列表中删除文件和listitem。但我希望看到一个解决方案,在一个步骤中完成这两项任务,而无需首先创建过滤的临时列表

// non-sense code example
lstFiles.ForEach(x => x.CreationTime < __now.AddDays(maxAge * -1), x => x.Delete())
    .Remove(x);
// or...
newList/IEnumerable = lstFiles.Where(x => x.CreationTime < __now.AddDays(maxAge * -1), x.Delete()).RemoveAll(x)

如果要在保持链接操作的同时执行多个操作,则可以使用Microsoft以及.do和.ForEach扩展名

lstFiles
   .Where(x => x.CreationTime < __now.AddDays(maxAge * -1))
   .Do(x => x.DoThing1())
   .Do(x => x.DoThing2())
   .ForEach(x => x.Remove());
lst文件
.Where(x=>x.CreationTime<\uu now.AddDays(maxAge*-1))
.Do(x=>x.DoThing1())
.Do(x=>x.DoThing2())
.ForEach(x=>x.Remove());

如果要在保持链接操作的同时执行多个操作,可以使用Microsoft的扩展名以及.do和.ForEach扩展名

lstFiles
   .Where(x => x.CreationTime < __now.AddDays(maxAge * -1))
   .Do(x => x.DoThing1())
   .Do(x => x.DoThing2())
   .ForEach(x => x.Remove());
lst文件
.Where(x=>x.CreationTime<\uu now.AddDays(maxAge*-1))
.Do(x=>x.DoThing1())
.Do(x=>x.DoThing2())
.ForEach(x=>x.Remove());

您可以使用不同的方法: 您可以使用一个
可观察集合
,而不是
列表
,将一个处理程序附加到事件
集合更改
,每次删除项目时,您都会删除关联的文件

collection.CollectionChanged += ContentCollectionChanged;
[...]
public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        foreach(var file in e.OldItems)
        {
            //Removed file
        }
    }
}

这样,您只需处理要在集合中删除的元素。

您可以使用不同的方法: 您可以使用一个
可观察集合
,而不是
列表
,将一个处理程序附加到事件
集合更改
,每次删除项目时,您都会删除关联的文件

collection.CollectionChanged += ContentCollectionChanged;
[...]
public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        foreach(var file in e.OldItems)
        {
            //Removed file
        }
    }
}

这样,您只需处理要在集合中删除的元素。

只需使您的
Delete()
方法返回bool,然后您就可以使用:

lstFiles.RemoveAll(x => x.CreationTime < _now.AddDays(maxAge * -1) && x.Delete());
lstFiles.RemoveAll(x=>x.CreationTime<\u now.AddDays(maxAge*-1)和&x.Delete();
如果&&语句的第一部分失败,则不会计算第二部分,因此只会对符合条件的文件进行删除


这还有一个额外的好处,即当删除失败时,它不会将文件从列表中删除。

只需使您的
delete()
方法返回bool,然后您就可以使用:

lstFiles.RemoveAll(x => x.CreationTime < _now.AddDays(maxAge * -1) && x.Delete());
lstFiles.RemoveAll(x=>x.CreationTime<\u now.AddDays(maxAge*-1)和&x.Delete();
如果&&语句的第一部分失败,则不会计算第二部分,因此只会对符合条件的文件进行删除


这还有一个额外的好处,即当删除失败时,它不会将文件从列表中删除。

list
的一种方法,它与Linq无关,它已经存在于.NET 2中。@TimSchmelter因此我将其标记为“无意义代码示例”。我的问题涉及到这方面的每一种方法,例如,
Where()
(用于过滤列表等)。标准的
ForEach
有什么问题吗?您在枚举列表时是否试图从列表中删除项?你不想这样做;它将失败。是
List
的一种方法,它与Linq无关,它已经存在于.NET2中。@TimSchmelter,因此我将其标记为“无意义代码示例”。我的问题涉及到这方面的每一种方法,例如,
Where()
(用于过滤列表等)。标准的
ForEach
有什么问题吗?您在枚举列表时是否试图从列表中删除项?你不想这样做;它将失败。这是最简单的实现方法,如果删除操作无法访问权限等,那么您就有了一个安全网。虽然这确实回答了问题,但这是一个非常糟糕的做法,因为您在一个看似布尔表达式的范围内造成了非常重要的副作用,因此,这将导致比稍长的备选方案可读性差得多的代码。@Servy我只是展示如何实现它,而不是认可这是一种最佳实践。我也不喜欢在一条语句中做两件谨慎的事情,因为这会导致代码很难理解,让bug更难发现。这就是为什么我不会否决这样的事情,我只是警告OP,虽然它看起来很圆滑,但使用它可能不是一个好主意。回答问题并不是反对你的理由。这是最简单的实现方法,如果删除操作无法访问权限等,你就有了一个安全网。虽然这确实回答了问题,但这是一个相当糟糕的做法,因为你在一个看起来只是布尔表达式的表达式中造成了一个非常重要的副作用,因此,这将导致比稍长的备选方案可读性差得多的代码。@Servy我只是展示如何实现它,而不是认可这是一种最佳实践。我也不喜欢在一条语句中做两件谨慎的事情,因为这会导致代码很难理解,让bug更难发现。这就是为什么我不会否决这样的事情,我只是警告OP,虽然它看起来很圆滑,但使用它可能不是一个好主意。你回答所问的问题没有什么不利于你的。