使用 Where 查询进行多项可选检查(以指定文件搜索选项)

Multiple optional checks with Where query (to specify file search options)

我创建了复选框,用户可以在其中设置它以进行文件搜索:

  1. 排除系统文件:on/off
  2. 排除隐藏文件:on/off
  3. 排除 read_only 个文件:on/off

现在我不知道如何将这三个不同的布尔语句与此代码行一起使用:

DirectoryInfo DirInfo = new DirectoryInfo(sCopyFilesFromFilePath);                    
GetDirsToCopy = 
   DirInfo.EnumerateDirectories(".", SearchOption.AllDirectories).Where( ? );

你可以使用暗示。在逻辑上 a -> b 被翻译成 !a || b,因此:

DirInfo.EnumerateDirectories(".", SearchOption.AllDirectories)
       .Where(x => !excludeSystem || (x.Attributes&FileAttributes.System) == 0);
       .Where(x => !excludeHidden || (x.Attributes&FileAttributes.Hidden) == 0);
       .Where(x => !excludeReadOnly || (x.Attributes&FileAttributes.ReadOnly) == 0);

这里我们假设 excludeSystemexcludeHiddenexcludeReadOnly 是您首先从复选框中提取的 bool

你当然也可以写成一个Where

解释(一.Where):

给定以下表达式

x => !excludeSystem || (x.Attributes&FileAttributes.System) == 0

你可以把它当成谓词来读。假设 excludeSystemfalse,那么 !excludeSystemtrue,因此所有目录都会成功。如果不是,则执行第二个操作数 (x.Attributes&FileAttributes.System) == 0

第二个操作数首先对 xAttributes 和常量 FileAttributes.System 按位 &。如果 Attributes 因此包含 FileAttributes.System,结果将不同于零。在这种情况下,第二个测试失败。换句话说,如果文件被排除并且文件是系统文件,你 return false

优化

如果您认为您将遍历数千个目录,您可以通过加快测试速度来提高代码的效率:

IEnumerable<DirectoryInfo> temp = DirInfo.EnumerateDirectories(".", SearchOption.AllDirectories);
if(excludeSystem) {
    temp = temp.Where((x.Attributes&FileAttributes.System) == 0);
}
if(excludeHidden) {
    temp = temp.Where((x.Attributes&FileAttributes.Hidden) == 0);
}
if(excludeReadOnly) {
    temp = temp.Where((x.Attributes&FileAttributes.ReadOnly) == 0);
}
GetDirsToCopy = temp;

这将(几乎)总是高效的,但它使代码不那么美观。