[英]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.