2016-05-26 6 views
1

У меня есть некоторые функции, которые позволяют пользователю выполнять поиск по нескольким каталогам для файлов определенного типа, а затем только путь этих файлов добавляется к listbox. Сейчас это делается через некоторые вложенные операторы foreach. Это будет извлечение сотен тысяч файловых путей, поэтому мне было любопытно, какие еще эффективные способы для этого?Должен ли я реорганизовать эти вложенные заявления foreach?

Кроме того, я знаю, что это звучит глупо, чтобы добавить, что многие предметы относятся к listbox. Я делаю то, что мне сказали. У меня есть чувство, что в будущем ему будет предложено избавиться, но файловые пути все равно придется хранить в списке где-нибудь.

Примечание: Я использую 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 
      } 
     } 
    } 
} 

Edit: Не уверен, если это имеет значение, но я использую WPFlistbox, не winforms.

+4

Одно слово ... [Linq] (https://msdn.microsoft.com/en-us/library/bb397933.aspx) –

+0

.. вы собираетесь добавлять «сотни тысяч путей файлов "в список? – stuartd

+0

Да, на данный момент это то, что человек, которого я делаю для желаний. В будущем есть шанс, что они не будут отображаться в списке, но все равно их нужно будет сохранить в списке. – pfinferno

ответ

-3

Вы можете реорганизовать его, или вы можете оставить его как есть.

Если вы реорганизуете его;

Ваш код будет более читабельным, понятным и многоразовым. Вам нужно написать пару методов.

И ваши методы могут быть использованы для других вещей, таких как ваш текущий метод.

И работает.

Если вы оставите это как есть;

Ваш код работает. Но трудно понять и прочитать. Трудно отлаживать в случае ошибки. Но работает.

+0

Почему код «трудно понять и читать» и «трудно отлаживать»? – stuartd

+0

Этот код достаточно читабельен, но с LINQ вы можете сделать это более эффективно и с меньшим кодом – Curious

+0

этот код содержит несколько вложенных foreach, но если вы разделите foreaches на методы, вы можете прочитать их легче. и когда вы отлаживаете, вы можете легко понять, что не так. –

1

Один из способов начать рефакторинг за пределами обучения Linq - использовать метод AddRange. Хорошее объяснение его преимуществ по сравнению с петлями для работы: https://stackoverflow.com/a/9836512/4846465

Однако, вероятно, нет ответа на этот вопрос.

foreach (var directoryPath in selectedDirectories) 
{ 
    foreach (string ext in (dynamic)ImageCB) 
    { 
     ListBox1.Items.AddRange(Directory.GetFiles(directoryPath, ext, SearchOption.AllDirectories).ToArray()); 
    } 
} 
+0

Хорошая идея, но я использую список WPF, который не имеет свойства 'AddRange'. – pfinferno

+1

Возможно, небольшое изменение вышеописанного фрагмента кода приведет к добавлению результатов Directory.GetFiles в локальный список , а затем установите этот List как ListBoxs.ItemsSource за пределами внешнего цикла for. Удачи, я мало знаю о WPF. –

+0

Хм, да, это хорошая идея. Я собираюсь сделать некоторые тесты производительности по сравнению с другими способами. Лучшим вариантом, вероятно, будет создание модели просмотра для хранения данных и привязка «listbox» к этому, но, к сожалению, остальная часть этой программы не написана именно так. – pfinferno