2011-03-30 6 views
1

복잡한 개체에서 값을 찾으려고합니다. 이미이 작업을 수행하는 도우미 클래스가 있다면 누구라도 알 수 있습니까?Reflection : 문자열 값, 반복적으로 검색 한 다음 경로를 검색하는 개체

"foo"가 포함 된 문자열 값을 찾은 다음 foo가있는 속성 경로를 반환하기 위해 무한 루프 보호를 관찰하면서 개체를 검색 할 수 있습니다. foo가 발견 된 경로 배열 . 그렇게하면

누군가가 나는이에게 자신을 편리 기존 코드를 수행하기 전에; 나는 가장 감사 할 것입니다.

답변

1

키는 현재 속성 값인 Stack을 유지하고, 재귀 적으로 값을 검색하는 동안 방문한 개체를 HashSet까지 건너 뛰고 건너 뜁니다. 또한 예외 처리에주의를 기울여 중간에 예외가 발생해도 스택이 엉망이되지 않도록해야합니다.

public static string[] FindPathToProperty(object item, string propertyValueToFind) 
    { 
     var pathToProperty = new Stack<string>(); 
     var visitedObjects = new HashSet<object> {item}; 

     FindPathToProperty(item, propertyValueToFind, pathToProperty, visitedObjects); 

     var finalPath = pathToProperty.ToArray(); 
     Array.Reverse(finalPath); 
     return finalPath; 
    } 

    private static bool FindPathToProperty(object item, string propertyValueToFind, Stack<string> pathToProperty, HashSet<object> visitedObjects) 
    { 
     foreach (var property in item.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
     { 
      try 
      { 
       var value = property.GetValue(item, null); 

       if (visitedObjects.Contains(value)) 
       { 
        continue;      
       } 

       visitedObjects.Add(value); 

       pathToProperty.Push(property.Name); 

       bool found = false; 
       try 
       { 
        found = propertyValueToFind.Equals(value) || 
          FindPathToProperty(value, propertyValueToFind, pathToProperty, visitedObjects); 
       } 
       finally 
       { 
        if (!found) 
        { 
         pathToProperty.Pop(); 
        } 
       } 
       if (found) 
       { 
        return true; 
       } 
      } 
      catch 
      { 
       continue; 
      } 
     } 

     return false; 
    } 

    public static void Test() 
    { 
     Test(new { X = "find" }, "X"); 
     Test(new { X = "no", Y = "find" }, "Y"); 
     Test(new { A = new { X = "no", Y = "find" } }, "A.Y"); 
    } 

    private static void Test(object item, string expected) 
    { 
     string actual = string.Join(".", FindPathToProperty(item, "find")); 
     Console.WriteLine("{0} : {1}\r\n  {2}", 
          actual == expected ? "ok " : "BAD", 
          expected, 
          actual); 
    } 
+0

이는 천재입니다! 정말 고맙습니다. 위 화살표가 버튼 이었으면 좋겠다. 여러개의 "업"이 가능하고 끈적한 테이프로 엔터 키를 누르고있을 수있다. –

+0

@Valamas, np, 우리는 리플렉션을 많이 사용합니다. 이것은 우리가 내부 공통 라이브러리에서 가지고있는 함수와 거의 같습니다. LINQ는 또한 리플렉션에서 실제로 잘 작동하지만 재귀 LINQ가 없기 때문에 여기서 도움이되지는 않습니다. –

+0

자식 속성으로 포함 된 IList 개체가 있으면 코드가 작동하지 않습니다. –

관련 문제