代码之家  ›  专栏  ›  技术社区  ›  GoldenAge

获取C中嵌套对象字段的完整路径#

c#
  •  0
  • GoldenAge  · 技术社区  · 6 年前

    假设我们有两个类:

    public class MyClass
    {
        public MyClass2 Foo { get; set; }
    }
    
    public class MyClass2
    {
        public int Blah { get; set; }
    }
    

    我希望显示blah属性的完整路径,但不包括命名空间,因此在本例中,预期结果是:

    MyClass.Foo.Blah
    

    我已经在调试模式下运行了这些东西,DAG在 MyClass 使用反射的对象 typeof(MyClass) . 最后,我在树中使用表达式找到了blah属性:

    ((System.Reflection.PropertyInfo[])((System.Reflection.TypeInfo)((System.Reflection.RuntimeMethodInfo)((System.Reflection.MemberInfo[])((System.Reflection.TypeInfo)((System.Reflection.RuntimeFieldInfo)((System.Reflection.FieldInfo[])((System.Reflection.TypeInfo)typeof(MyClass)).DeclaredFields)[0]).DeclaringType).DeclaredMembers)[0]).ReturnType).DeclaredProperties)[0]
    

    看起来有点笨重。 有人知道一些“聪明”的方法,我怎样才能收到结果,但不需要硬编码字段的名称?干杯

    2 回复  |  直到 6 年前
        1
  •  1
  •   Derviş Kayımbaşıoğlu    6 年前

    我能想到的最简单的方法是

    Type cType = typeof(MyClass);
    var prop = cType.GetProperties()[0];
    var innerPropName = prop.PropertyType.GetProperties()[0].Name;
    Console.WriteLine($"{nameof(MyClass)}.{prop.Name}.{innerPropName}");
    

    编辑

    我使用递归函数以便能够循环访问属性

    public static string GetClassDetails(Type t, ref IList<string> sList, string str = null )
    {
        if (sList is null) sList = new List<string>();
        if (str is null) str = t.Name;
    
        foreach (var propertyInfo in t.GetProperties())
        {
            str = $"{str}.{propertyInfo.Name}";
            if (propertyInfo.PropertyType.IsClass)
                str = $"{str}.{GetClassDetails(propertyInfo.PropertyType, ref sList, str)}";
    
            sList.Add(str);
            str = "";
        }
    
        return str;
    }
    

    你可以称之为

     IList<string> sList = null;
     var result = GetClassDetails(cType, ref sList);
    

    实例类

    public class MyClass
    {
        public MyClass2 Foo { get; set; }
        public int Baz { get; set; }
    }
    
    public class MyClass2
    {
        public int Blah { get; set; }
    }
    
        2
  •  0
  •   Xiaoy312    6 年前

    你可以使用 ToString 获取路径的表达式的方法。更换lambda部件需要进行最小的修改( x => x YourClassName :

    usage: ReflectionHelper<MyClass>.GetPath(x => x.Foo.Blah) // -> "MyClass.Foo.Blah"
    
    public class ReflectionHelper<T>
    {
        public static string GetPath<TProperty>(Expression<Func<T, TProperty>> expr)
        {
            var name = expr.Parameters[0].Name;
    
            return expr.ToString()
                .Replace($"{name} => {name}", typeof(T).Name);
        }
    }