C# 我应该重构这些嵌套的foreach语句吗?
我有一些功能,允许用户在多个目录中搜索特定类型的文件,然后将这些文件的路径添加到C# 我应该重构这些嵌套的foreach语句吗?,c#,wpf,foreach,nested-loops,C#,Wpf,Foreach,Nested Loops,我有一些功能,允许用户在多个目录中搜索特定类型的文件,然后将这些文件的路径添加到列表框中。现在,它是通过一些嵌套的foreach语句完成的。它将检索数十万个文件路径,所以我很好奇还有什么其他有效的方法来实现这一点 另外,我知道在列表框中添加那么多项目听起来很愚蠢。我只是在做别人叫我做的事。我有一种感觉,将来它会被要求删除,但是文件路径仍然必须存储在某个地方的列表中 注意:我正在使用WindowsAPICodePack获取一个允许多目录选择的对话框 List<string> selec
列表框中。现在,它是通过一些嵌套的foreach
语句完成的。它将检索数十万个文件路径,所以我很好奇还有什么其他有效的方法来实现这一点
另外,我知道在列表框中添加那么多项目听起来很愚蠢。我只是在做别人叫我做的事。我有一种感觉,将来它会被要求删除,但是文件路径仍然必须存储在某个地方的列表中
注意:我正在使用WindowsAPICodePack
获取一个允许多目录选择的对话框
List<string> selectedDirectories = new List<string>();
/// <summary>
/// Adds the paths of the directories chosen by the user into a list
/// </summary>
public void AddFilesToList()
{
selectedDirectories.Clear(); //make sure list is empty
var dlg = new CommonOpenFileDialog();
dlg.IsFolderPicker = true;
dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = true;
dlg.ShowPlacesList = true;
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
selectedDirectories = dlg.FileNames.ToList(); //add paths of selected directories to list
}
}
/// <summary>
/// Populates a listbox with all the filepaths of the selected type of file the user has chosen
/// </summary>
public void PopulateListBox()
{
foreach (string directoryPath in selectedDirectories) //for each directory in list
{
foreach (string ext in (dynamic)ImageCB.SelectedValue) //for each file type selected in dropdown
{
foreach (string imagePath in Directory.GetFiles(directoryPath, ext, SearchOption.AllDirectories)) //for each file in specified directory w/ specified format(s)
{
ListBox1.Items.Add(imagePath); //add file path to listbox
}
}
}
}
List selectedDirectories=newlist();
///
///将用户选择的目录路径添加到列表中
///
public void AddFilesToList()
{
selectedDirectories.Clear();//确保列表为空
var dlg=新建CommonOpenFileDialog();
dlg.IsFolderPicker=true;
dlg.AddToMostRecentlyUsedList=false;
dlg.allownonfilesystemems=false;
dlg.ensureRefileExists=true;
dlg.EnsurePathExists=true;
dlg.EnsureReadOnly=false;
dlg.EnsureValidNames=true;
dlg.Multiselect=true;
dlg.ShowPlacesList=true;
if(dlg.ShowDialog()==CommonFileDialogResult.Ok)
{
selectedDirectories=dlg.FileNames.ToList();//将所选目录的路径添加到列表中
}
}
///
///用用户所选文件类型的所有文件路径填充列表框
///
public void PopulateListBox()
{
foreach(selectedDirectories中的字符串directoryPath)//用于列表中的每个目录
{
foreach(字符串ext in(dynamic)ImageCB.SelectedValue)//对于在下拉列表中选择的每个文件类型
{
foreach(Directory.GetFiles中的字符串imagePath(directoryPath,ext,SearchOption.AllDirectories))//对于指定目录中的每个文件,使用指定格式
{
ListBox1.Items.Add(imagePath);//将文件路径添加到listbox
}
}
}
}
编辑:不确定它是否有区别,但我使用的是WPF
列表框,而不是winforms
您可以重构它,也可以保持原样
如果你重构它
您的代码将更具可读性、可理解性和可重用性。
您只需要编写几个方法
您的方法可以用于其他事情,比如您当前的方法
而且有效
如果你让它保持原样
你的代码可以工作。但是很难理解和阅读。在出现错误的情况下很难调试。
但是它是有效的。在学习Linq之外开始重构它的一种方法是使用AddRange方法。与for循环相比,它的性能优势有一个很好的解释:
然而,这个问题可能没有答案
foreach (var directoryPath in selectedDirectories)
{
foreach (string ext in (dynamic)ImageCB)
{
ListBox1.Items.AddRange(Directory.GetFiles(directoryPath, ext, SearchOption.AllDirectories).ToArray());
}
}
一个字。。你打算在列表框中添加“数十万个文件路径”吗?是的,到目前为止,这正是我为之做这件事的人想要的。将来它们可能不会显示在列表框中,但仍必须保存在某个位置的列表中。@DavidPine以前没有使用过太多Linq,我会仔细阅读。我确实在某个地方读到过,在引擎盖下面,它执行的基本操作与foreach循环相同。这是个好主意,但我使用的是WPF的listbox,它没有AddRange
属性。也许对上面的代码片段稍作修改,可以将Directory.GetFiles的结果添加到本地列表中,然后将该列表设置为ListBoxs.ItemsSource位于最外层for循环的外部。祝你好运,我对WPF知之甚少。嗯,是的,这是个好主意。我将在这方面做一些性能测试,与其他方法进行比较。最好的方法可能是创建一个视图模型来存储数据,并将列表框绑定到该视图模型,但不幸的是,此程序的其余部分不是这样编写的。为什么代码“难以理解和读取”和“难以调试”?此代码可读性足够,但使用LINQ,这段代码包含多个嵌套的foreach,但如果将foreach拆分为方法,则可以更轻松地阅读。当您调试时,您可以很容易地理解什么是错误的。