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

时间:2019-01-07 21:43:08

标签: c#

让我们说我们有两个类:

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

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

我想显示Blah属性的完整路径,但不包括名称空间,因此在这种情况下,预期结果将是:

MyClass.Foo.Blah

我已经在调试模式下运行了这些东西,并使用反射MyClasstypeof(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 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

您可以使用表达式的ToString方法来获取路径。需要最小的修改才能用x => x替换lambda部分(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);
    }
}