Wie ein System.Collections.Generic.List erhalten, die alle Fieldinfo ist ein Objekt eines Typs hält T bis zu dem Objekt in der Klassenhierarchie?

StackOverflow https://stackoverflow.com/questions/1006192

  •  06-07-2019
  •  | 
  •  

Frage

Ich versuche, einen vorhandenen Code wiederverwenden ... aber ohne Erfolg. Hier ist der 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 
War es hilfreich?

Lösung

Beachten Sie, dass es sehr selten ist, dass Sie zu Chaos mit FieldInfo müssen; Felder sind selten öffentlich, und Sie sollten in der Regel die PropertyInfos (GetProperties()) werden. GetFields wird jedoch funktionieren. Für den öffentlichen Bereichen, nur GetFields(); Auch für private Felder müssen Sie 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));
        }
    }
}

Andere Tipps

Haben Sie versucht, BindingFlags.FlattenHierarchy Angabe?

Danke für die Antworten, die ich versuchte, so etwas zu tun (ich bin immer noch nicht sicher, dass .ToString () wäre der beste Weg, um Werte eines Feldes zu vergleichen:

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 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top