简体   繁体   English

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

[英]Get full path to the nested object's field in C#

Lets say we have two classes: 可以说我们有两个类:

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

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

I would like to display the full path to the Blah property but without including the namespace, so in this case, the expected result would be: 我想显示Blah属性的完整路径,但不包括名称空间,因此在这种情况下,预期结果将是:

MyClass.Foo.Blah

I've run the stuff in the debug mode and dag in the MyClass object using reflection typeof(MyClass) . 我已经在调试模式下运行了这些东西,并使用反射typeof(MyClass)MyClass对象中进行了调试。 In the end, I found the Blah property in the tree using the expression: 最后,我使用以下表达式在树中找到了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]

which looks a bit clunky. 看起来有点笨拙。 Anybody knows some "smart" way how can I receive the result but without hardcoding the names of the fields? 有人知道某种“智能”方式如何才能收到结果,但不对字段名称进行硬编码吗? Cheers 干杯

the simplest way I can think of is 我能想到的最简单的方法是

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

Edit 编辑

I have used recursive function in order to be able to loop through the Properties 我使用了递归函数,以便能够遍历属性

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

You can call it 你可以叫它

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

Example Class 示例类

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

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

You can use ToString method of an expression to get the path. 您可以使用表达式的ToString方法获取路径。 Minimal modification is needed to replace the lambda part ( x => x ) with YourClassName : 需要最小的修改才能用YourClassName替换lambda部分( x => x ):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM