问题描述
根据此示例:
public class a
{
public string a1 {get; set;} = "va1";
public int a2 {get; set;} = 20;
}
public class b
{
public string b1 {get; set;} = "vb1";
public int b2 {get; set;} = 40;
}
public class c
{
public string c1 {get; set;} = "vc1";
public int c2 {get; set;} = 60;
public a class_a {get; set;} = new a();
public b class_b {get; set;} = new b();
}
我正在尝试构建一种递归返回所有属性值的方法,在本例中为class c
,但我想使其对任何其他类通用。
static void GetValues(Object obj)
{
Type t = obj.GetType();
PropertyInfo[] properties = t.GetProperties();
foreach (var property in properties)
{
if (property.PropertyType.Name == "a" || property.PropertyType.Name == "b")
{
Console.WriteLine($"--- Properties class: {property.PropertyType.Name} ---");
GetValues(property.GetValue(obj,null));
}
else
{
Console.WriteLine($"Type: {property.PropertyType.Name} {property.Name} = {property.GetValue(obj,null).ToString()}");
}
}
}
该函数返回以下结果:
Type: String c1 = vc1
Type: Int32 c2 = 60
--- Properties class: a ---
Type: String a1 = va1
Type: Int32 a2 = 20
--- Properties class: b ---
Type: String b1 = vb1
Type: Int32 b2 = 40
问题
是否有一种方法可以知道某个属性是否为class
类型,而不是专门针对类a
或b
进行检查?
我想替换以下代码行:
if (property.PropertyType.Name == "a" || property.PropertyType.Name == "b")
通过类似的方式:
if (property.IsClass)
我已在 Rextester
上设置了此示例解决方法
您就在那儿-您只需要记住您是否在询问属性类型是否是一类:
if (property.PropertyType.IsClass)
,
使用反射,您可以查询任何类型的属性。请注意,结构也可能具有属性。因此,递归所有类型而不仅仅是类都是有意义的。
但是请注意,这对于某些内置类型(例如具有string
属性的Length
和具有许多DateTime
和{{1 }}。更糟糕的是,它的属性DayOfWeek
再次是Ticks
,从而创建了无限递归。因此,通过尝试一个错误,您可能必须排除某些类型,甚至实现检测递归的机制,或者至少限制最大嵌套级别。
以下是排除示例:
Date
调用DateTime
的结果
(我添加了private static readonly HashSet<Type> ExcludedTypes =
new HashSet<Type> { typeof(string),typeof(DateTime) };
static void GetValues(Object obj,int level)
{
Type t = obj.GetType();
PropertyInfo[] properties = t.GetProperties();
foreach (var property in properties) {
if (property.GetIndexParameters().Length == 0) { // Exclude indexers
Console.Write(new string(' ',4 * level));
Type pt = property.PropertyType;
object value = property.GetValue(obj,null);
Console.WriteLine($"{pt.Name} {property.Name} = {value}");
if (value != null && !ExcludedTypes.Contains(pt)) {
GetValues(value,level + 1);
}
}
}
}
和GetValues(new c(),0);
属性以使其更加有趣):
DateTime a3