Вопрос

В настоящее время я разрабатываю приложение, которое использует пространство имен 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, каждый раз передавая следующий каталог (дочерний элемент).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top