簡體   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