繁体   English   中英

.Where出现错误,在foreach循环中使用lambda表达式处理无效参数

[英]Getting an error with .Where using a lambda expression in a foreach loop for invalid arguments

我正忙于在VS2010(大学分配)中创建索引Windows窗体应用程序的文件/文件夹。 出于测试目的,文件/文件夹索引编制类在控制台应用程序中

我使用以下内容浏览文件夹,它运行良好,并将所有文件夹名称写入文件指定驱动器中。 我主要是从msdn资源(使用递归方法)将其组合在一起,并进行了修改,因为它不包含获取文件夹名称。

我想排除某些文件夹,并决定使用lambda表达式,并且带有单词列表的List将是最快的,尽管我可以通过if比较来放置遍历数组的循环,但在我看来这会比较慢(我对C#中的复杂工作还不了解。 我对lambda表达式进行了简要介绍,以查看自己是否可以修复它。

这是我的代码,没有任何文件夹排除在外

class Program
{
    static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();
    private static List<string> _excludedDirectories = new List<string>() { "Windows", "AppData", "$WINDOWS.~BT", "MSOCache", "ProgramData", "Config.Msi", "$Recycle.Bin", "Recovery", "System Volume Information", "Documents and Settings", "Perflogs" };

    //method to check
    static bool isExcluded(List<string> exludedDirList, string target)
    {
        return exludedDirList.Any(d => new DirectoryInfo(target).Name.Equals(d));
    }

    static void Main()
    {

        string[] drives = {"C:\\"};

        foreach (string dr in drives)
        {
            DriveInfo di = new System.IO.DriveInfo(dr);

            // Here we skip the drive if it is not ready to be read. 
            if (di.IsReady)
            {
                DirectoryInfo rootDir = di.RootDirectory;
                WalkDirectoryTree(rootDir);
            }
            else
            {
                Console.WriteLine("The drive {0} could not be read", di.Name);
                continue;
            }
        }

        // Write out all the files that could not be processed.
        Console.WriteLine("Files with restricted access:");
        foreach (string s in log)
        {
            Console.WriteLine(s);
        }
        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key");
        Console.ReadKey();
    }

    static void WalkDirectoryTree(System.IO.DirectoryInfo root)
    {
        FileInfo[] files = null;
        DirectoryInfo[] subDirs = null;
        StreamWriter filex = new System.IO.StreamWriter("test.txt", true);

        if (filex != null)
        {
            filex.Close();
        }

        // Process all the folders directly under the root 
        try
        {
            subDirs = root.GetDirectories();
        }// This is thrown if even one of the folders requires permissions greater than the application provides. 
        catch (UnauthorizedAccessException e)
        {
            log.Add(e.Message);
        }
        catch (System.IO.DirectoryNotFoundException e)
        {
            Console.WriteLine(e.Message);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        // Process all the files directly under the root 
        try
        {
            files = root.GetFiles("*.*");
        }// This is thrown if even one of the files requires permissions greater than the application provides. 
        catch (UnauthorizedAccessException e)
        {
            log.Add(e.Message);
        }
        catch (System.IO.DirectoryNotFoundException e)
        {
            Console.WriteLine(e.Message);
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }

        if (files != null)
        {
            filex = new StreamWriter("test.txt", true);
            foreach (FileInfo fi in files)
            {
                // In this example, we only access the existing FileInfo object. If we 
                // want to open, delete or modify the file, then 
                // a try-catch block is required here to handle the case 
                // where the file has been deleted since the call to TraverseTree().
                Console.WriteLine(fi.FullName);
                filex.WriteLine(fi.FullName);
            }
            filex.Close();
        }

        if (subDirs != null)
        {
            //var filteredDirs = Directory.GetDirectories(root.Name).Where(d => !isExcluded(_excludedDirectories, d));
            foreach (DirectoryInfo subds in subDirs)
            {
                filex = new StreamWriter("test.txt", true);
                Console.WriteLine(subds.FullName);
                filex.WriteLine(subds.FullName);
                filex.Close();

                foreach (DirectoryInfo dirInfo in subDirs)
                {
                    // Resursive call for each subdirectory.
                    WalkDirectoryTree(dirInfo);
                }
            }
            filex.Close();// Because at end filestream needs to close
        }
    }
}

所以我尝试将.Where(d =>!isExcluded(_excludedDirectories,d))合并到我的循环中:

if (subDirs != null)
        {
            //var filteredDirs = Directory.GetDirectories(root.Name).Where(d => !isExcluded(_excludedDirectories, d));
            foreach (DirectoryInfo subds in subDirs.Where(d => !isExcluded(_excludedDirectories, d)))
            {
                filex = new StreamWriter("test.txt", true);
                Console.WriteLine(subds.FullName);
                filex.WriteLine(subds.FullName);
                filex.Close();

                foreach (DirectoryInfo dirInfo in subDirs)
                {
                    // Resursive call for each subdirectory.
                    WalkDirectoryTree(dirInfo);
                }
            }
            filex.Close();// Because at end filestream needs to close
        }

问题:惊叹号后出现错误,提示“最佳重载方法匹配具有一些无效的参数...”我应该做/更改,应该采用更简单的路线并使用循环,如果在循环中编写if语句文件夹名称? 因为我也知道该怎么做。 并记住我目前正在做的方式(至少要尝试)是因为我认为这样会更优化/更快。 如果没有太大的不同,请告诉我,我将使用我所知道的方式。

我的猜测是,我试图通过在foreach中放置.where来做一件不好的事情,并且我意识到了为什么是或可能是。

我也尝试过:

if (subDirs != null)
        {
            //var filteredDirs = Directory.GetDirectories(root.Name).Where(d => !isExcluded(_excludedDirectories, d));
            foreach (DirectoryInfo subds in subDirs)
            {
              if ((d => !isExcluded(_excludedDirectories, d)))
              {
                filex = new StreamWriter("test.txt", true);
                Console.WriteLine(subds.FullName);
                filex.WriteLine(subds.FullName);
                filex.Close();

                foreach (DirectoryInfo dirInfo in subDirs)
                {
                    // Resursive call for each subdirectory.
                    WalkDirectoryTree(dirInfo);
                }
              } 

            }
            filex.Close();// Because at end filestream needs to close
        }

但出现错误,因为它不是委托,所以无法将lamba表达式转换为bool类型

如果您想查看其他代码,请告诉我,然后我将其添加,似乎有些过多。

d在这里不是string ,而是DirectoryInfo 更改isExcluded方法签名以正确处理d的类型。

您的签名是:

static bool isExcluded(List<string> exludedDirList, string target)

它应该是:

static bool isExcluded(List<string> exludedDirList, DirectoryInfo target)

您的方法最终将是:

//method to check
static bool isExcluded(List<string> exludedDirList, DirectoryInfo target)
{
    return exludedDirList.Any(d => target.Name.Equals(d));
}

问题在这里:

foreach (DirectoryInfo subds in subDirs.Where(d => !isExcluded(_excludedDirectories, d)))

subDirs是DirectoryInfo类型,您的isExcluded将字符串作为第二个参数。

你要:

foreach (DirectoryInfo subds in subDirs.Where(d => !isExcluded(_excludedDirectories, d.Name)))

暂无
暂无

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

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