【问题标题】:Is there a way to make this C# method shorter and more readable with the help of Linq?有没有办法在 Linq 的帮助下使这个 C# 方法更短、更易读?
【发布时间】:2010-05-12 15:29:07
【问题描述】:

以下工作,但我想 - 因为它都是基于IEnumerableLinq 可以派上用场这里很好。顺便说一句,是否有与Directory.GetFiles() 等效的方法,它会返回一个 IEnumerable 而不是数组?如果它存在,那么它会使代码运行得更快吗?问题的最后一部分受到 Python 语言的启发,该语言偏爱轻量级生成器而不是具体列表。

    private IEnumerable<string> getFiles(string strDirectory, bool bCompressedOnly)
    {
        foreach (var strFile in Directory.GetFiles(strDirectory))
        {
            // Don't add any existing Zip files since we don't want to delete previously compressed files.
            if (!bCompressedOnly || Path.GetExtension(strFile).ToLower().Equals(".zip"))
            {
                yield return strFile;
            }
        }

        foreach (var strDir in Directory.GetDirectories(strDirectory))
        {
            foreach (var strFile in getFiles(strDir, bCompressedOnly))
            {
                yield return strFile;
            }
        }
    }

【问题讨论】:

  • .NET Framework 4.0 中有新的Directory.Enumerate* 方法,它们返回一个 IEnumerable。

标签: linq .net-3.5 directory


【解决方案1】:

我不认为我更喜欢这个,但是......

return (
        from file in Directory.GetFiles(strDirectory)
        where !bCompressedOnly
            || Path.GetExtension(file).ToLower().Equals(".zip")
        select file
    ).Concat(
        from directory in Directory.GetDirectories(strDirectory)
        from file in getFiles(directory, bCompressedOnly)
        select file
    );

.NET 4 中的新功能:

private static IEnumerable<string> getFiles(string strDirectory,
    bool bCompressedOnly)
{
    return Directory.EnumerateFiles(strDirectory,
        bCompressedOnly ? "*.zip" : "*.*", SearchOption.AllDirectories);
}

【讨论】:

  • SearchOption 在 .NET 4 之前可用
  • Directory.EnumerateFiles 是 .NET 4 中的新功能:msdn.microsoft.com/en-us/library/dd383571.aspx
  • 文件名搜索模式是否区分大小写?另外...如果文件恰好没有扩展名,"*" 是否足以满足搜索模式?
  • 是的,它是不敏感的(假设您在所有文件名都不敏感的 Windows 上运行)
  • 搜索*.* 会找到所有文件,即使是那些没有扩展名的文件(我已经测试过了)。
【解决方案2】:

我的得分为零,因为我让 ReSharper 为我做这件事,但这是它的建议。

private IEnumerable<string> getFiles(string strDirectory, bool bCompressedOnly) {
    foreach (var strFile in Directory.GetFiles(strDirectory).Where(strFile => !bCompressedOnly || Path.GetExtension(strFile).ToLower().Equals(".zip"))) {
        yield return strFile;
    }

    foreach (var strFile in Directory.GetDirectories(strDirectory).SelectMany(strDir => getFiles(strDir, bCompressedOnly))) {
        yield return strFile;
    }
}

它们都是任意更改,在某些方面我认为(至少在第一个循环中)它们会混淆逻辑,但要么接受要么放弃。另外,如果您还没有,请查看ReSharper。 :)

【讨论】:

  • 是的,在尝试阅读后,我肯定更喜欢原始代码,但这确实回答了这个问题。
  • 所以我们可以看到,有时更多就是更好。虽然,第二个循环实际上相当干净。也许使用那个并保留第一个原样。
【解决方案3】:

有一个DirectoryGetFiles 重载方法,它接受一个搜索模式字符串和一个System.IO.SearchOption 枚举。 SearchOption 值之一是 AllDirectories。如果使用它,您将摆脱方法的第二个循环。

private IEnumerable<string> getFiles(string strDirectory, bool bCompressedOnly)
{
    foreach (var strFile in Directory.GetFiles(strDirectory, bCompressedOnly ? "*.zip" : "*.*", SearchOption.AllDirectories))
    {
        yield return strFile;
    }
}

【讨论】:

  • AllDirectories 表示递归搜索,实际上并不返回目录。
  • @ck,这个方法也不返回目录。
  • @ck,OP 的代码只返回文件,而不是目录,所以听起来AllDirectories 正是需要的。
猜你喜欢
  • 2019-03-23
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 2011-08-14
  • 2020-07-29
  • 1970-01-01
  • 2020-06-04
相关资源
最近更新 更多