让我们说我们有两个类:
public class MyClass
{
public MyClass2 Foo { get; set; }
}
public class MyClass2
{
public int Blah { get; set; }
}
我想显示Blah属性的完整路径,但不包括名称空间,因此在这种情况下,预期结果将是:
MyClass.Foo.Blah
我已经在调试模式下运行了这些东西,并使用反射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]
看起来有点笨拙。 有人知道某种“智能”方式如何才能收到结果,但不对字段名称进行硬编码吗?干杯
答案 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);
}
}