2015-02-02 4 views
1

사용자가 Tree-Hierarchy의 모든 장치를 볼 수있는 USB 장치 스캐너를 만들었습니다. 처음에는 효과가 있었지만 기쁨을 감수하면서 코드 품질이 좋지 않음을 알았습니다 (코드 예제 참조).트리 계층 구조를 만드는 C# 재귀 메서드

더 나은 이해를 위해 : 다음은 트리 모양 및 코드가 제공하는 방식입니다. 이제 코드 예제

BUS-Type    Device Description 
----------   ------------------- 
---------- 
PCI  |   |USB-Controller 
USB  |   |----|USB-Root Hub 
USB  |   |----|-----|Generic USB Hub 
USB  |   |----|-----|-----|USB Device 
USB  |   |----|-----|Generic USB Hub 
.      . 
.      . 
And so on. 

:

if (hierarchyDeviceZero.Children.Count != 0) { 
    for (int usbHierarchyLevelOne = 0; usbHierarchyLevelOne < hierarchyDeviceZero.Children.Count; usbHierarchyLevelOne++) { 
     foreach (var hierarchyDeviceOne in usbDeviceTree.USBDeviceNodes.Where(
      d1 => d1.HardwareID.Equals(hierarchyDeviceZero.Children[usbHierarchyLevelOne].HardwareID)) 
     ) { 
      Console.WriteLine("{0}\t|\t\t|---|{1}", hierarchyDeviceOne.EnumeratorName, hierarchyDeviceOne.Description); 
      if (hierarchyDeviceOne.Children.Count != 0) { 
       for (int usbHierarchyLevelTwo = 0; usbHierarchyLevelTwo < hierarchyDeviceZero.Children.Count; usbHierarchyLevelTwo++) { 
        foreach (var hierarchyDeviceTwo in usbDeviceTree.USBDeviceNodes.Where(
         d1 => d1.HardwareID.Equals(hierarchyDeviceOne.Children[usbHierarchyLevelTwo].HardwareID)) 
        ) { 
         Console.WriteLine("{0}\t|\t\t |---|{1}", hierarchyDeviceTwo.EnumeratorName, hierarchyDeviceTwo.Description); 
         if (hierarchyDeviceTwo.Children.Count != 0) { 
          for (int usbHierarchyLevelThree = 0; usbHierarchyLevelThree < hierarchyDeviceZero.Children.Count; usbHierarchyLevelThree++) { 
           foreach (var hierarchyDeviceThree in usbDeviceTree.USBDeviceNodes.Where(
            d1 => d1.HardwareID.Equals(hierarchyDeviceTwo.Children[usbHierarchyLevelThree].HardwareID)) 
           ) { 
. 
. 
. 
. 
And so on (until 10th Hierarchylevel). 

, 내가 어떻게 재귀 방법으로이 문제를 넣을 수 있습니다 내 질문? 몇 가지 자습서를 시도했지만 다소 그 값을 덮어 쓰지 않고 메서드가 10 회 호출 할 수있는 방법을 이해하지 못했습니다 ... 여러분이 내가 뭘 하려는지 이해해 주길 바랍니다.

추신 : 죄송합니다.

+4

여기에 더 나은 될 수 있습니다 codereview.stackexchange.com –

+2

는 paremeter으로 호출 할 수있는 방법에 리팩토링'방법 (및 매개 변수)의 범위에서 선언 – DrKoch

+4

변수 level'에 로컬 * 해당 메소드의 특정 호출 *. 따라서 재귀 호출은 별도의 로컬 변수 집합을 사용합니다. –

답변

1

데이터 구조에서 나는 이상한 것을 본다, 즉 노드가 모두 UsbDeviceTree 인 것 같지만 개별 노드에는 .Children 속성이있다.

그냥 제발 노드 .Children을 사용할 수 있다면 이런 식으로 할 수 있다고 생각합니다.

public class Device { 
    public int HardwareId { get; set; } 
    public Device[] Children {get; set; } 
    /* ...the rest... */ 
}        

void DisplayNodes(IEnumerable<Device> currentCollection, int indentation) { 
    foreach (var currentNode in currentCollection) { 
     // Display current node 
     Console.WriteLine(
      ... 
      display the node and 
      use the indentation parameter to control the --- or ---|--- 
      ... 
     ); 

     if (currentNode.Children != null) { 
      DisplayNode(currentNode.Children, indentation + 1); 
     } 
    } 
} 

// Data 
IEnumerable<Device> allDevices = usbDeviceTree.USBDeviceNodes; 
IEnumerable<Device> rootDevices = allDevices 
    .Where(x => x.IsRootNode /* TODO */) 
    .ToArray(); 

// Display 
DisplayNodes(rootDevices, 1); 
+0

고맙습니다. 그게 날 많이 도와 줬어! 그 구조에 대해서, 나는 그것에 대해서도 노력하고 있습니다.). – Megajin

관련 문제