2012-02-08 3 views
0

저는 리플렉션을 처음 접했습니다. 재귀 적으로 객체를 반복하고, 일반 목록과 일반 배열을 다른 객체를 포함하는 필드로 가지고있는 가장 좋은 방법은 무엇입니까?목록/배열을 반복적으로 반복합니다.

using System; 
[AttributeUsage(AttributeTargets.Field)] 
public class ExportForTranslationAttribute : System.Attribute 
{ 
    public ExportForTranslationAttribute() { } 
} 

가 그럼 난 특정 객체에서 시작하고 거기에서 깊은 이동 :

자세한 내용은

는 사실은 내가 번역을 위해 내보낼 필드를 표시하기 위해 다음과 같은 특성을 만들었습니다. (지금 전체 방법을 복사했습니다.)

개인 Int64 timesMaxDeepnessReached = 0;

private void searchForExportableStringsInObject(object obj, int deepness) 
{ 
    if (deepness > maxDeepness) 
    { 
     timesMaxDeepnessReached++; 
     return; 
    } 

    if (obj != null) 
    { 
     //only follow serializable objects! 
     var objAttributes = obj.GetType().GetCustomAttributes(true); 
     foreach (var oa in objAttributes) 
     { 
      if (oa.GetType() == typeof(SerializableAttribute)) 
      { 
       var fields = obj.GetType().GetFields(); 
       if (fields == null || !fields.Any()) 
       { return; } 

       foreach (var fieldInfo in fields) 
       { 
        //1. handle string fields that are directly on the component 
        #region directly on object 
        var attributes = fieldInfo.GetCustomAttributes(true); 

        bool hadExportAttribute = false; 

        foreach (var a in attributes) 
        { 
         if (a.GetType() == typeof(ExportForTranslationAttribute)) 
         { 
          Debug.Log("found something!"); 
          hadExportAttribute = true; 

          if (fieldInfo.FieldType == typeof(string)) 
          { 
           try 
           { 
            Debug.Log("info.GetValue= " + fieldInfo.GetValue(obj)); 
            addKeyWhenNotExisting((string)fieldInfo.GetValue(obj)); 
           } 
           catch (Exception ex) { Debug.Log("error while getting value to export: " + ex); } 
          } 
          else if (fieldInfo.FieldType == typeof(string[])) 
          { 
           Debug.Log("found string[]!"); 
           try 
           { 
            Debug.Log("info.GetValue= " + fieldInfo.GetValue(obj)); 
            foreach (var item in (string[])fieldInfo.GetValue(obj)) 
            { 
             addKeyWhenNotExisting(item); 
            } 
           } 
           catch (Exception ex) { Debug.Log("error while getting value to export: " + ex); } 
          } 
          else if (fieldInfo.FieldType == typeof(List<string>)) 
          { 
           Debug.Log("found List<string>!"); 
           try 
           { 
            Debug.Log("info.GetValue= " + fieldInfo.GetValue(obj)); 
            foreach (var item in (List<string>)fieldInfo.GetValue(obj)) 
            { 
             addKeyWhenNotExisting(item); 
            } 
           } 
           catch (Exception ex) { Debug.Log("error while getting value to export: " + ex); } 
          } 
          else 
          { 
           Debug.LogWarning("Can only add ExportForTranslation-Attribute to string values and collection of string values. Not on the type: " + fieldInfo.FieldType); 
          } 
         } 
        } 
        #endregion //directly on object 
       } 
      } 
      else if (oa.GetType() == typeof(List<>)) 
      { 
       try 
       { 
        foreach (var item in (IList)oa) 
        { 
         searchForExportableStringsInObject(item, ++deepness); 
        } 
       } 
       catch (Exception ex) { }//{ Debug.Log("error while getting value to export: " + ex); } 
      } 
      else if (oa.GetType() == typeof(Array)) 
      { 
       try 
       { 
        foreach (var item in (Array)oa) 
        { 
         searchForExportableStringsInObject(item, ++deepness); 
        } 
       } 
       catch (Exception ex) { }//{ Debug.Log("error while getting value to export: " + ex); } 
      } 
     } 
    } 
    else 
    { 
     return; 
    } 
} 
+0

우선, 모든 예외 사항을 삼키는 이유는 무엇입니까? – CodesInChaos

+0

당신이 정말로하려는 일에 도움이되는 좀 더 구체적인 배경 정보가 도움이 될 것이라고 생각합니다. –

+1

+1 나는 특별히 잘 쓰여진 것은 아니라고 동의하며, 아마도 그것이 분명하지는 않다는 것에 동의한다. 그러나 나는 그것을 올바르게 해석했다면 그것이 어떤 장점을 가지고 있다고 생각한다. –

답변

1

oa.GetType() 당신에게 인스턴스의 유형, oa.PropertyType을 필요로하는 속성의하지 Type을 가져옵니다.

편집

나는 이것을 함께 넣어 집 주위에 갈 수 있고, 내가 더 나은, 또는 적어도 더 간결 방법, 그러나 아마이 당신을 위해 무엇을 찾고있는 같은 것입니다 거기 내기 :

class Program 
    { 
     static void Main(string[] args) 
     { 
      var testType = new TestType {GenList = new List<string> {"test", "type"}}; 

      foreach(var prop in typeof (TestType).GetProperties()) 
      { 
       if (prop.PropertyType.IsGenericType) 
       { 
        var genericTypeArgs = prop.PropertyType.GetGenericArguments(); 

        if (genericTypeArgs.Length!=1 || !(genericTypeArgs[0] == typeof(string))) 
         continue; 

        var genEnum = typeof (IEnumerable<>).MakeGenericType(genericTypeArgs); 

        if (genEnum.IsAssignableFrom(prop.PropertyType)) 
        { 
         var propVal = (IList<string>)prop.GetValue(testType, BindingFlags.GetProperty, null, null, null); 

         foreach (var item in propVal) 
          Console.WriteLine(item); 
        } 
       } 
      } 

      Console.ReadLine(); 
     } 
    } 

    public class TestType 
    { 
     public IList<string> GenList { get; set; } 
    } 
+0

답변으로 질문을 표시했습니다. 사실 저는 작업 환경을 바꿨 기 때문에 문제를 다시 보지 않을 것입니다. – SwissCoder

1

속성은 결코 List<>이 아닙니다. 따라서 oa.GetType() == typeof(List<>)은 항상 거짓입니다.

사용자 지정 속성을 가져 오는 대신 GetFields() 필드 또는 GetProperties() 속성을 사용하려는 경우 일 수 있습니다.

List<T>과 동일한 지 확인하는 대신 유형이 IEnumerable<T>인지 확인하는 것이 좋습니다.

+0

Myles McConnels의 권장 사항을 시험해보기 위해 전체 코드를 추가했습니다. – SwissCoder

관련 문제