Цикл через DirectoryEntry или любую иерархию объектов - C # - PullRequest
2 голосов
/ 01 апреля 2009

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

Мой вопрос: каков наилучший способ создания цикла для сбора информации, если вы не знаете количество подкаталогов в вашем объекте?

(Это может быть применено к любому типу объекта, которому вы не знаете иерархию объектов)

Ответы [ 5 ]

5 голосов
/ 01 апреля 2009

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

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<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);
            }
        }
    }
}
2 голосов
/ 01 апреля 2009

Вы должны написать рекурсивную функцию как ...

DirectoryEntry root = new DirectoryEntry(path);
DoForEveryNode(root);

void DoForEveryNode(DirectoryEntry node)
{
    // do something..

    foreach(DirectoryEntry child in node.Children)
    {
        DoForEveryNode(child);
    }
}
1 голос
/ 01 апреля 2009

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

1 голос
/ 01 апреля 2009

Один из вариантов - использовать рекурсию. Установите этот код в функции, которая затем вызывает себя внутри цикла foreach, каждый раз передавая следующий каталог (дочерний элемент)

1 голос
/ 01 апреля 2009

Вы можете использовать функцию, которая рекурсивно вызывает себя для детей. условие выхода: больше нет детей и т.д ..

...