如何递归和反思性地获取所有可能的字段名称路径的列表?

时间:2019-04-23 13:17:17

标签: c# recursion reflection key-value

我试图获取一个字符串集合,该字符串给我所有班级成员的字段名称,并用.分隔。例如:

public class Apple
{
    public Banana MyBanana = new Banana();
    public Cranberry MyCranberry = new Cranberry();
}

public class Banana
{
    public int MyNumber = 5;
    public Cranberry MyCranberry = new Cranberry();
}

public class Cranberry
{
    public string MyString = "Hello!";
    public int MyOtherNumber = 10;
}

public class Demo
{
    public List<string> GetFields(Type Apple)
    {
        //I can't figure this out
        //But it should return a list with these elements:
        var result = new List<string>
        {
            "MyBanana.MyNumber",
            "MyBanana.MyCranberry.MyString",
            "MyBanana.MyCranberry.MyOtherNumber",
            "MyCranberry.MyString",
            "MyCranberry.MyOtherNumber"
        };
        return result;
    }
}

我认为需要某种递归和反射,但是在编写了几个小时的代码后,我需要一些帮助。

之所以需要它,是因为我正在访问第三方代码,该代码使用这些文件路径作为各自值的键。

一个失败尝试的例子:

    private List<string> GetFields(Type type)
    {
        var results = new List<string>();
        var fields = type.GetFields();
        foreach (var field in fields)
        {
            string fieldName = field.Name;
            if (field.ReflectedType.IsValueType)
            {
                results.Add(fieldName);
            }
            else
            {
                results.Add(field.Name + GetFields(field.FieldType));
            }
        }
        return results;
    }

我找到了几个相关的问题,但是没有一个与我的问题完全相符,我自己也无法做出跳转:Recursively Get Properties & Child Properties Of A Classhttps://stackoverflow.c“ om / questions / 6196413 / how-to使用反射递归打印对象属性的值,Recursively Get Properties & Child Properties Of An Object.NET, C#, Reflection: list the fields of a field that, itself, has fields

1 个答案:

答案 0 :(得分:3)

您需要递归实现:

HashSet<Type> nonRecursiveTypes = new HashSet<Type> { typeof(System.Int32), typeof(System.String) }; // add other simple types here
IEnumerable<string> GetFields(object obj)
{
    foreach (var field in obj.GetType().GetFields())
    {
        if (nonRecursiveTypes.Contains(field.FieldType))
            yield return field.Name;
        else
            foreach (var innerFieldName in GetFields(field.GetValue(obj)))
                yield return field.Name + "." + innerFieldName;
    }
}