2009-06-17 2 views
1

私は既存のコードを再利用しようとしていますが、成功しません。コードスニペットは次のとおりです。System.Collections.Generic.Listを取得する方法タイプTのオブジェクトのすべてのFieldInfoをクラス階層のオブジェクトまで保持する<FieldInfo>?

using System; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.Text; 
using System.Reflection; 

namespace GenApp.Utils.Reflection 
{ 
    class FieldTraverser 
    { 


     public static string SearchFieldValue(object obj, int MaxLevel, string strFieldMeta , ref object fieldValue) 
     { 
      if (obj == null) 
       return null; 
      else 
      { 
       StringBuilder sb = new StringBuilder(); 
       bool flagShouldStop = false; 
       FieldTraverser.PrivDump(sb, obj, "[ObjectToDump]", 0, MaxLevel , ref flagShouldStop , ref fieldValue); 
       return sb.ToString(); 
      } 
     } //eof method 



     public static object GetFieldValue(object obj, string fieldName, ref bool flagShouldStop, ref object objFieldValue) 
     { 
      FieldInfo fi; 
      Type t; 

      t = obj.GetType(); 
      fi = t.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
      if (fi == null) 
       return null; 
      else 
      { 

       if (fi.Name.Equals(fieldName)) 
       { 
        objFieldValue = fi.GetValue(obj); 
        flagShouldStop = true; 
       } 
       return fi.GetValue(obj); 
      } //eof else 
     } //eof method 


     protected static void DumpType(string InitialStr, StringBuilder sb, object obj, 
      int level, System.Type t, int maxlevel , ref bool flagShouldStop , ref object objFieldValue 
      ) 
     { 
      FieldInfo[] fi; 
      fi = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
      if (t == typeof(System.Delegate)) return; 
      foreach (FieldInfo f in fi) 
      { 
       PrivDump(sb, f.GetValue(obj), f.Name, level + 1, maxlevel , ref flagShouldStop , ref objFieldValue); 
       if (flagShouldStop == true) 
        return; 
      } 
      object[] arl; 
      int i; 
      if (obj is System.Array) 
      { 
       try 
       { 
        arl = (object[])obj; 
        for (i = 0; i < arl.GetLength(0); i++) 
        { 
         PrivDump(sb, arl[i], "[" + i + "]", level + 1, maxlevel, ref flagShouldStop, ref objFieldValue); 
         if (flagShouldStop == true) 
          return; 
        } 
       } 
       catch (Exception) { } 
      } 
     } 




     protected static void PrivDump(StringBuilder sb, object obj, string objName, int level, int MaxLevel, ref bool flagShouldStop, ref object objFieldValue) 
     { 

      if (obj == null) 
       return; 
      if (MaxLevel >= 0 && level >= MaxLevel) 
       return; 

      string padstr; 
      padstr = ""; 
      for (int i = 0; i < level; i++) 
       if (i < level - 1) 
        padstr += "|"; 
       else 
        padstr += "+"; 
      string str; 
      string[] strarr; 
      Type t; 
      t = obj.GetType(); 
      strarr = new String[7]; 
      strarr[0] = padstr; 
      strarr[1] = objName; 
      strarr[2] = " AS "; 
      strarr[3] = t.FullName; 
      strarr[4] = " = "; 
      strarr[5] = obj.ToString(); 
      strarr[6] = "\r\n"; 
      sb.Append(String.Concat(strarr)); 
      if (obj.GetType().BaseType == typeof(ValueType)) 
       return; 
      FieldTraverser.DumpType(padstr, sb, obj, level, t, MaxLevel, ref flagShouldStop , ref objFieldValue); 
      Type bt; 
      bt = t.BaseType; 
      if (bt != null) 
      { 
       while (!(bt == typeof(Object))) 
       { 
        str = bt.FullName; 
        sb.Append(padstr + "(" + str + ")\r\n"); 
        FieldTraverser.DumpType(padstr, sb, obj, level, bt, MaxLevel , ref flagShouldStop , ref objFieldValue); 
        bt = bt.BaseType; 
        if (bt != null) 
         continue; 
        break; 
       } while (bt != typeof(Object)) ; 
      } 
     } //eof method 
    }//eof class 
    } //eof namespace 
+1

最長質問ネームバッジ –

+1

が...少なくともあなたの注意をつかんで知ってはいけない;) –

答えて

3

FieldInfoを混乱させることは非常にまれであることに注意してください。フィールドはほとんど公開されていません。通常、PropertyInfoGetProperties())を使用してください。ただし、GetFieldsが動作します。パブリックフィールドの場合は、ちょうどGetFields()です。プライベートフィールドにもあなたはBindingFlagsを必要とする:私はこのような何かをしようとしていた答えを

class Foo { 
    public string abc; 
} 
class Bar : Foo { 
    private int def; 
} 
static class Program { 
    static void Main() { 
     object obj = new Bar(); 
     FieldInfo[] fields = obj.GetType().GetFields(
      BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

     foreach(FieldInfo field in fields) { 
      Console.WriteLine(field.Name + " = " + field.GetValue(obj)); 
     } 
    } 
} 
1

System.Type.GetFields()を使用してください。

+0

おかげで、BindingFlags.FlattenHierarchyある可能性があり.. –

1

BindingFlags.FlattenHierarchyを指定してみましたか?

+0

おかげで、私はコメントを経由して答えたとAjaxあなたの答えは更新されませんでした。 )だからAJAXは必ずしも良いとは言えない –

0

感謝を(私はまだ.ToString()は、フィールドの値と比較するための最良の方法だろうことを確認していません:?

using System; 
using System.Reflection; 


class Foo 
{ 
    public string abc; 
} 
class Bar : Foo 
{ 
    private int def = 0; 
} 
static class Program 
{ 
    static void Main() 
    { 
     object obj = new Bar(); 
     object objShouldNotHaveIt = new Foo(); 
     object objShouldHaveIt = new Bar(); 

      string myQuestion = "How-to get a System.Collections.Generic.List<FieldInfo> list which holds all FieldInfo’s of an object of a Type T up to the Object in the class hierarchy in C# ?"; 


     if (Program.SearchFieldByValue(objShouldNotHaveIt, "def", 0)) 
      Console.WriteLine(" NOK"); 

     if (Program.SearchFieldByValue(objShouldHaveIt , "def" , 0)) 
      Console.WriteLine(" OK "); 

      Console.WriteLine("Is a " + myQuestion.Length.ToString() + " chars long string considered as long question ? "); 



     Console.ReadLine(); 
    } //eof main 


    public static bool SearchFieldByValue (object obj , string strFieldName , object objFieldValue) 
    { 

     FieldInfo[] fields = obj.GetType().GetFields(
     BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

     foreach (FieldInfo field in fields) 
     { 
      object objFieldValueReflected = field.GetValue(obj) ; 
      Console.WriteLine(field.Name + " = " + field.GetValue(obj)); 
      if (objFieldValueReflected != null && objFieldValue.ToString().Equals(objFieldValueReflected.ToString())) 
       return true; 
      else 
       continue; 
     } 
     return false; 

    } //eof method 






} //eof class 
関連する問題