Цикл через DirectoryEntry или любую иерархию объектов – C#
-
22-08-2019 - |
Вопрос
В настоящее время я разрабатываю приложение, которое использует пространство имен System.DirectoryServices для создания объекта DirectoryEntry и перебирает всю иерархию для сбора информации.
Я не знаю количества дочерних записей для каждого объекта DirectoryEntry в иерархии, поэтому я не могу создать N вложенных циклов для пауков через свойство Children.
Вот мой пример псевдокода:
//root directory
DirectoryEntry root = new DirectoryEntry(path);
if(DirectoryEntry.Childern != null)
{
foreach(DirectoryEntry child in root.Children)
{
//loop through each Children property unitl I reach the last sub directory
}
}
Мой вопрос: как лучше всего создать цикл для сбора информации, если вы не знаете количество подкаталогов в вашем объекте?
(Это можно применить к любому типу объекта, иерархия объектов которого вам не известна)
Решение
Используйте рекурсивную функцию, если вы не знаете глубину иерархии и вам нужно пройти все уровни вниз.Ниже приведен пример использования обхода в глубину.
using (DirectoryEntry root = new DirectoryEntry(someDN))
{
DoSomething(root);
}
function DoSomething(DirectoryEntry de)
{
// Do some work here against the directory entry
if (de.Children != null)
{
foreach (DirectoryEntry child in de.Children)
{
using (child)
{
DoSomething(child);
}
}
}
}
Альтернативно, без рекурсии, вы можете выполнить обход, добавив структуру данных Queue или Stack и сохранив объекты, которые вы видели, но еще не посетили.
Queue<DirectoryEntry> queue = new Queue<DirectoryEntry>();
DirectoryEntry root = new DirectoryEntry(someDN);
queue.Add(root);
while (queue.Any())
{
using (DirectoryEntry de = queue.Dequeue())
{
// Do some work here against the directory entry
if (de.Children != null)
{
foreach (DirectoryEntry child in de.Children)
{
queue.Enqueue(child);
}
}
}
}
Другие советы
Вам нужно написать рекурсивную функцию как...
DirectoryEntry root = new DirectoryEntry(path);
DoForEveryNode(root);
void DoForEveryNode(DirectoryEntry node)
{
// do something..
foreach(DirectoryEntry child in node.Children)
{
DoForEveryNode(child);
}
}
Вы можете использовать функцию, которая рекурсивно вызывает себя для дочерних элементов.условие выхода:детей больше нет и т. д.
Один из вариантов — использовать рекурсию.Установите этот код в функцию, которая затем вызывает себя внутри цикла foreach, каждый раз передавая следующий каталог (дочерний элемент).
Добро пожаловать в чудесный мир рекурсии.Вам нужна функция, которая принимает каталог в качестве аргумента.Учитывая этот каталог, он просматривает все дочерние каталоги и для каждого из них...называет себя.