【问题标题】:How do I recursively and reflectively get a list of all possible field name paths?如何递归地和反射地获取所有可能的字段名称路径的列表?
【发布时间】:2019-09-12 16:39:53
【问题描述】:

我正在尝试获取一个字符串集合,该集合为我提供所有班级成员的字段名称,以.s 分隔。例如:

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 Class, https://stackoverflow.c"om/questions/6196413/how-to-recursively-print对象属性使用反射的值,Recursively Get Properties & Child Properties Of An Object.NET, C#, Reflection: list the fields of a field that, itself, has fields

【问题讨论】:

  • Apple.GetFields(BindingFlags.Public).ToList(); 这会给你一个List&lt;Fields&gt;。然后,您可以通过将字段名称转换为您需要的 List&lt;string&gt; 来转换它
  • 你目前的结果是什么?您需要 Reflection (GetFields) 来获取第一级属性,然后对于每个属性,获取它的类型并再次递归地使用 GetField。

标签: c# recursion reflection key-value


【解决方案1】:

你需要一个递归实现:

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;
    }
}

【讨论】:

  • 就是这样++
  • 效果很好!还帮助我发现了代码中的错误,这就是我之前所有尝试都失败的原因。谢谢!!
  • if(field.FieldType.IsValueType)代替if(nonRecursiveTypoes.Contains(field.FieldType))有什么危险吗?
  • 值类型并不总是简单类型,结构体也是值类型。此外,您不会停留在字符串上,因为它们是引用类型。这真的取决于你想做什么,但我认为它不适合你的场景。
猜你喜欢
  • 2022-01-08
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 2021-07-27
  • 2021-12-07
相关资源
最近更新 更多