System.collections.generic.list 를 얻는 방법은 클래스 계층 구조에서 T 형 객체의 모든 FieldInfo를 보유하고 있습니까?

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

  •  06-07-2019
  •  | 
  •  

문제

기존 코드를 재사용하려고하지만 성공하지 못했습니다. 코드 스 니펫은 다음과 같습니다.

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 
도움이 되었습니까?

해결책

당신이 엉망이 될 필요가 매우 드 rare니다. FieldInfo; 필드는 거의 공개되지 않으며 일반적으로 사용해야합니다. PropertyInfoS (GetProperties()). 하지만, 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));
        }
    }
}

다른 팁

지정해 보셨습니까? BindingFlags.FlattenHierarchy?

이런 일을하려고했던 답변에 감사드립니다 (.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 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top