2012-01-28 3 views
2

나는 이것이 가능한 것처럼 보이는 것보다 훨씬 간단하게이 작업을 수행 할 수있을 것이라고 생각했습니다.개체 그래프 검색

객체 그래프에서 특정 유형의 모든 인스턴스를 가져올 수있는 가장 효율적인 방법이 필요합니다.

리플렉션을 사용하여이 유형의 인스턴스를 찾고 다른 모든 복합 유형 및 컬렉션을 계속 찾는 객체 속성을 통해 작업을 시작했습니다. 그것은 많은 일뿐만 아니라 누군가가 과거에해야 할 일의 종류처럼 느껴지기 시작했습니다. 따라서 작업량과 테스트가 많이 필요하기 전에 프레임 워크 내에서 빠른 승리를 놓치고 있는지, 또는 이런 종류의 작업을 수행하기위한 라이브러리에 대한 권장 사항이 있는지 묻습니다.

왜 이것을하고 싶습니까? 다른 유형의 파생 유형이 있습니다. 이 유형은 일반적인 특성을 가지고 있으며 더 중요한 것은 오류를 식별하는 특정 오류 인 HasErrors입니다. 이 유형은 모델 구축에 사용됩니다. 각 모델은 다릅니다. 어떤 단순하고 얕은 일부 복잡하고 깊은. 각 복합 노드는 일반적으로이 유형에서 파생되는 모음 또는 사용자 정의 유형입니다. 이 모든 HasErrors 속성을 검사하는 모든 인스턴스를 빠르게 탐색하는 방법이 필요합니다. true의 모든 인스턴스는 모델에 오류가 있음을 나타냅니다.

Model 
    CustomerId (int) 
    CustomerDetails : MyType 
     Name (string) 
     DoB (DateTime) 
     Addresses (Collection<Address : MyType>) 
      [Line1 (string) 
      Line2 (string)] 

바라건대 이런 종류의 설명.

interface IComponent 
{ 
    IEnumerable<IComponent> Components { get; } 
} 

을 한 후 전체 개체 그래프를 걸어이 인터페이스를 사용 : 당신이 당신의 유형으로 구성 전체 개체 그래프를 통과 할 경우

+1

나만의 유형입니까? 그것은 당신의 복합 구조입니까? –

+3

임의의 유형의 임의의 그래프를 탐색 할 계획이라면 - 이것이 작업 부하 일 것입니다 (다른 것들과 순환 참조를 피하는 것을 포함하여). 진정한 질문은 다시 정의하고, 작업을보다 단순하게 만드는 방법입니다. – mfeingold

+0

@Martin 두 지점 모두 예. 인스턴스에서이 함수를 수행해야하는 기본 클래스 메서드가 있습니다.찾고있는 유형의 인스턴스 속성과 속성입니다. – voiddog

답변

0

, 당신은 그들 모두가 같은 인터페이스를 구현 할 수 있습니다. 그래프에 사이클이 포함될 수 있다면 방문한 정점의 HashSet<IComponent>과 같은 것을 사용하여이를 방지해야합니다. 해당 인터페이스를 구현하는 경우

, 반복자 블록은 유용 할 수있다 :

class FamilyMember : IComponent 
{ 
    IEnumerable<IComponent> IComponent.Components 
    { 
     get 
     { 
      if (Father != null) 
       yield return Father; 

      if (Mother != null) 
       yield return Mother; 

      foreach (var child in Children) 
       yield return child; 
     } 
    } 
} 

이미 지루한 수 있습니다 이렇게 객체 그래프의 일부 유형을 많이가있는 경우. 그렇다면 성능 저하에 신경 쓰지 마세요. 반향을 사용하는 것이 더 나을 것입니다.

+0

죄송합니다. 잠시 지났지 만 답변에 감사드립니다. 나는 한 번 훑어 보았고 실제 코드로 연극을했고 나는 당신이 제안하고있는 것을 볼 수있다. 불행히도 나는 많은 종류가 있습니다. 더 많은 시간이있을 때 이것을 사용하거나 비슷한 것을 사용하여 이것을 답으로 표시 할 수 있습니다. 다시 건배. – voiddog

0

이는 "상자 밖에서 생각"대답 무언가이다,하지만 난 당신이 아래로 트리를 검색한다고 생각하지 않습니다, 나는 당신이 트리까지 오류를 를 전파한다고 생각합니다.

모든 개체에 부모 또는 모델의 루트 노드에 대한 참조를 제공하십시오. 객체의 HasErrors 속성이 참일 때, 사용 된 참조의 종류에 따라, 모든 조상을 통해 루트로, 또는 루트에 직접 루트로 트리 위로 메시지를 보냅니다.

이렇게하면 모델에 오류가있는 경우 즉시 알 수 있으며 복잡하고 값 비싸며 잠재적으로 효과가없는 트리의 하향식 검색을 구현할 필요가 없습니다.

+0

이것은 처음에 생각했던 것과 비슷합니다. 모든 레벨에 기본 클래스를 적용하지 않으므로 루트에 직접 가야합니다. 그래도 좋은 제안입니다. 시간을내어 주셔서 감사합니다. – voiddog