Loop através DirectoryEntry ou qualquer hierarquia de objetos - C #
-
22-08-2019 - |
Pergunta
Atualmente, estou desenvolvendo um aplicativo que usa o namespace System.DirectoryServices para criar um objeto DirectoryEntry e percorrer toda a hierarquia para coletar informações.
Eu não sei o número de entradas de criança para cada objeto DirectoryEntry na hierarquia, então não posso criar um número N de loops aninhados para aranhas através da propriedade Crianças
Aqui está o meu exemplo de código pseudo:
//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
}
}
A minha pergunta é, qual é a melhor maneira de criar um loop para coletar informações, se assim não sabe o número de sub-diretórios em seu objeto?
(Isto pode ser aplicado a qualquer tipo de objeto que você não sabe a hierarquia do objeto)
Solução
Use uma função recursiva, se você não sabe a profundidade da hierarquia e necessidade de percorrer para baixo através de todos os níveis. Abaixo está um exemplo usando travessia em profundidade.
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);
}
}
}
}
Como alternativa, sem recursão, você pode fazer um percurso pela adição de uma estrutura de dados fila ou pilha e armazenar os objetos que você já viu, mas não reembolsaram visitou ainda.
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);
}
}
}
}
Outras dicas
Você tem que escrever função recursiva como ...
DirectoryEntry root = new DirectoryEntry(path);
DoForEveryNode(root);
void DoForEveryNode(DirectoryEntry node)
{
// do something..
foreach(DirectoryEntry child in node.Children)
{
DoForEveryNode(child);
}
}
Você pode usar uma função que forma recursiva chama a si mesmo sobre as crianças. condição de saída: não mais crianças etc ..
Uma opção é usar recursão. Definir esse código em uma função que, em seguida, chama a si mesmo dentro do loop foreach, passando o próximo diretório (item filho) cada vez
Bem-vindo ao maravilhoso mundo da recursividade. Você precisa de uma função que aceita uma Directory como um argumento. Dado que diretório, ele procura todos os diretórios filho e para cada um ... chama-se.