2012-06-25 3 views
2

필자는 재귀 적으로 클래스의 모든 속성을 통과해야하며 속성이 문자열 일 경우 사용자 지정 논리를 수행해야합니다. 재귀 라인에 넣어야 할 것을 조언 해주세요.C에서 속성 정보에서 참조를 얻는 방법 #

void ProcessAllStrings<T>(ref T objToRip) 
{ 
    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 
    Type typeParameterType = typeof (T); 

    foreach (PropertyInfo p in typeParameterType.GetProperties(flags)) 
    { 
     Type currentNodeType = p.PropertyType; 
     if (currentNodeType == typeof (String)) 
     { 
      //here I do my custom string handling. Code deleted 
     } 
      //if non primitive and non string then recurse. (nested/inner class instances) 
      // see http://stackoverflow.com/questions/4444908/detecting-native-objects-with-reflection 
     else if (currentNodeType != typeof (object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object) 
     { 
      //I need to get the reference to this property which happens to be a nested class 
      //but propertyInfo only provides GetValue(). No GetReference available.. 
      ProcessAllStrings(ref "dont know what to put here"); 
     } 
    } 
} 
+0

'ref' 또는 generics'T'를 사용하는 특별한 이유는 무엇입니까? 아마도'typeParameterType'은'objToRip' 대신에 메소드에 대한 입력 매개 변수 여야합니다. EDIT : 무한 재귀로 실행되는 것을 조심해야 할 수도 있습니다 : 사용자 정의 유형이 자신의 인스턴스를 (또는 속성을 따라 체인이 그렇다면) 계속 반복해서 실행하고 싶지는 않습니다. –

+0

모든 답글에 대해 thx. 매우 도움이됩니다. 내 요구 사항은 xsd.exe에 의해 생성 된 많은 xml 클래스를 통과하고 xml 클래스의 모든 문자열 노드로 일부 사용자 지정 논리를 수행하는 것입니다. 그러므로 은 일반적인 사용자 생성 클래스 일 수 있기 때문에. – Gullu

답변

2

을 할 ProcessAllStrings(currentNodeType);를 호출 할 수 있습니다. 단지 함수에 다시 속성 값을 전달 재귀하려면

  else if (currentNodeType != typeof (object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object) 
      { 
       object propVal = p.GetValue(objToRip,null); 

       if(propVal != null) ProcessAllStrings(ref propVal); 
      } 

을 나는 또한뿐만 아니라 인덱스 속성에 대한 핸들러를 추가하는 것이 좋습니다 것입니다.

+0

thx Sir. 그 값이 심판이 아니라고 나에게 일어난 적 없다 !! – Gullu

0

메서드에서 개체 참조를 원하므로 재귀가 작동하도록 모든 중첩 클래스의 인스턴스를 만들어야합니다. 당신이 정말로 원하는 것은 Type 정보를 대신 전달하는 것입니다.

objToRip 대신 Type typeParameterType을 인수로 사용하십시오.

그럼 당신은 내가 값 참조입니다 생각은 참조 형의 경우 재귀에게

2

기본적으로 내가 코멘트에서 말한 것과 Mangist가 말한 것. 여기에 중첩 된 유형 참조에 무한 루프를 확인하는 구현의 :

private void ProcessAllStrings(Type objectType, HashSet<Type> typesChecked) 
{ 
    if (typesChecked == null) 
     typesChecked = new HashSet<Type>(); 

    if (typesChecked.Contains(objectType)) 
     return; 

    typesChecked.Add(objectType); 

    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 

    foreach (PropertyInfo p in objectType.GetProperties(flags)) 
    { 
     Type currentNodeType = p.PropertyType; 
     if (currentNodeType == typeof (String)) 
     { 
      //here I do my custom string handling. Code deleted 
      Console.WriteLine("Found String Property: " + currentNodeType.FullName + " -> " + p.Name); 
     } 
      //if non primitive and non string then recurse. (nested/inner class instances) 
      // see http://stackoverflow.com/questions/4444908/detecting-native-objects-with-reflection 
     else if (currentNodeType != typeof (object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object) 
     { 
      //I need to get the reference to this property which happens to be a nested class 
      //but propertyInfo only provides GetValue(). No GetReference available.. 
      ProcessAllStrings(currentNodeType, typesChecked); 
     } 
    } 
} 

그래서, 이런 클래스와 말은, FooFoo 다시 가리키는 Bar이 통지, 그래서 우리는 그렇지 않은 테스트 할 수 있습니다 무한 루프 :

public class Foo 
{ 
    public string Prop1 { get; set; } 
    public Bar Prop2 { get; set; } 
} 

public class Bar 
{ 
    public string BarProp { get; set; } 
    public Foo NestedFoo { get; set; } 
} 

당신은 같은 그것을 호출 할 수는 :

ProcessAllStrings(typeof(Foo), null); 
+0

+1. 아주 훌륭하고 강력한 솔루션. 노력을 감사하십시오. 무한 루프 상황이 없으므로 위에서 Dtanley가 제공하는보다 간단한 솔루션을 사용하겠습니다. thx – Gullu

0

당신은 동적 t을 사용할 수 있습니다 ype 대신 generic type :

public static void ProcessAllStrings(dynamic objToRip) 
{ 
    if (objToRip == null) return; 
    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 
    Type typeParameterType = objToRip.GetType(); 

    foreach (PropertyInfo p in typeParameterType.GetProperties(flags)) 
    { 
     Type currentNodeType = p.PropertyType; 
     if (currentNodeType == typeof(String)) 
     { 
      //here I do my custom string handling. Code deleted 
     } 
     else if (currentNodeType != typeof(object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object) 
     { 
      ProcessAllStrings(p.GetValue(objToRip, null)); 
     } 
    } 
} 
+0

괜찮습니다. 나는 동적 인 유형을 읽을 것이다. 이것을 결코 사용하지 않았다. 고마워 – Gullu

관련 문제