views:

392

answers:

4

I am trying to reuse an existing code ... but with no success . Here is the code snippet:

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  A: 

Use System.Type.GetFields()?

David Schmitt
Thanks , may be with BindingFlags.FlattenHierarchy ..,
YordanGeorgiev
+1  A: 

Have you tried specifying BindingFlags.FlattenHierarchy?

Paolo Tedesco
Thanks , I just replied via comment and the ajax call did not refresh your answer ... ; ) So AJAX is not always good
YordanGeorgiev
+3  A: 

Note that it is very rare you need to mess with FieldInfo; fields are rarely public, and you should generally be using the PropertyInfos (GetProperties()). However, GetFields will work. For public fields, just GetFields(); for private fields too you need 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));
        }
    }
}
Marc Gravell
A: 

Thanks for the answers I was trying to do something like this ( I am still not sure that .ToString() would be the best way to compare to values of a field:

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
YordanGeorgiev