2009-04-01 18 views
2

現在、System.DirectoryServices名前空間を使用してDirectoryEntryオブジェクトを作成し、階層全体をループして情報を収集するアプリケーションを開発しています。DirectoryEntryまたは任意のオブジェクト階層をループする - C#

私は、階層内の各DirectoryEntryオブジェクトの子エントリの番号がわからないので、私はここで子供のプロパティを介してスパイダーに

をネストされたループのN番号を作成することはできませんが、私の擬似コードの例です:

//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

階層の深さを知らず、すべてのレベルを横断する必要がある場合は、再帰関数を使用します。 深さ優先のトラバースを使用する例を以下に示します。

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); 
      } 
     } 
    } 
} 

また、再帰せずに、あなたが見てきたが、まだ訪れたhaventはオブジェクトをキューまたはスタックのデータ構造を追加して格納することにより、トラバースを行うことができます。

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); 
      } 
     } 
    } 
} 
+0

これは、ところで、再帰が実際に問題を処理するための良い方法ですの良い例です。ファイルシステム自体が深さ制限を課しているので、スタックを吹き飛ばすべきではありません。しかし、ツリーにループがある場合には、リンクするために注意が必要です。 –

+0

@jeffmaphone:DirectoryEntryは、実際にはファイルシステムではなくLDAPサーバーを指しています。私はLDAPの深さ制限についてはわかりませんが、ループがある場合は、アクセスする各エントリのGUIDを記録し、同じエントリを2回訪問すると再帰を停止するのが最も簡単な方法です。 –

+0

foreach-loopの中で 'using(child){...}'を使って、あなた自身の後にきれいにしてください。 http://stackoverflow.com/questions/41378746/disposing-during-foreach/41378945#41378945 – Born2Smile

1

あなたは再帰的に子供たちに自分自身を呼び出す関数を使用することができます(これは、オブジェクト階層を知っていない任意の型のオブジェクトに適用することができます)。 終了条件:これ以上子供などはありません。

1

1つのオプションは再帰を使用することです。毎回次のディレクトリ(子項目)を渡して、foreachループ内で自分自身を呼び出す関数にそのコードを設定します。

1

再帰の素晴らしい世界へようこそ。引数としてDirectoryを受け入れる関数が必要です。そのディレクトリを指定すると、それはすべての子ディレクトリを検索し、それぞれについて...自身を呼び出します。あなたはのように再帰関数を記述する必要があり

2

...

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

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

    foreach(DirectoryEntry child in node.Children) 
    { 
     DoForEveryNode(child); 
    } 
}