gpt4 book ai didi

c# - 递归例程获取PropertyInfo

转载 作者:太空狗 更新时间:2023-10-29 23:17:41 27 4
gpt4 key购买 nike

我正在尝试创建一个递归例程,该例程将为指定对象(在 .NET 3.5 中)下的所有成员检索 PropertyInfo。直接成员的一切都在工作,但它也需要解析嵌套类(及其嵌套类等)。

我不明白如何处理解析嵌套类的部分。您将如何编写这部分代码?

public class ObjectWalkerEntity
{
public object Value { get; set; }
public PropertyInfo PropertyInfo { get; set; }
}


public static class ObjectWalker
{
// This will be the returned object
static List<ObjectWalkerEntity> objectList = new List<ObjectWalkerEntity>();

public static List<ObjectWalkerEntity> Walk(object o)
{
objectList.Clear();
processObject(o);
return objectList;
}

private static void processObject(object o)
{
if (o == null)
{
return;
}

Type t = o.GetType();

foreach (PropertyInfo pi in t.GetProperties())
{
if (isGeneric(pi.PropertyType))
{
// Add generic object
ObjectWalkerEntity obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else
{
////// TODO: Find a way to parse the members of the subclass...
// Parse each member of the non-generic object
foreach (Object item in pi.PropertyType)
{
processObject(item);
}
}
}

return;
}

private static bool isGeneric(Type type)
{
return
Extensions.IsSubclassOfRawGeneric(type, typeof(bool)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(string)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(int)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(UInt16)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(UInt32)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(UInt64)) ||
Extensions.IsSubclassOfRawGeneric(type, typeof(DateTime));
}

编辑:我采纳了 Harlam 的一些建议,并提出了一个可行的解决方案。这会处理嵌套类和列表。

我已经用以下内容替换了之前通过 propertyinfo 的循环

foreach (PropertyInfo pi in t.GetProperties())
{
if (isGeneric(pi.PropertyType))
{
// Add generic object
ObjectWalkerEntity obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else if (isList(pi.PropertyType))
{
// Parse the list
var list = (IList)pi.GetValue(o, null);
foreach (object item in list)
{
processObject(item);
}
}
else
{
// Parse each member of the non-generic object
object value = pi.GetValue(o, null);
processObject(value);
}
}

我还添加了一个新的检查来查看某物是否是一个列表。

private static bool isList(Type type)
{
return
IsSubclassOfRawGeneric(type, typeof(List<>));
}

感谢您的帮助!

最佳答案

我认为这对您有用。这里的想法是从每次调用 ProcessObject() 返回一个可枚举对象。然后将这些调用滚动到调用者中 List<ObjectWalkerEntity> .

public class ObjectWalkerEntity
{
public object Value { get; set; }
public PropertyInfo PropertyInfo { get; set; }
}

public static class ObjectWalker
{
public static List<ObjectWalkerEntity> Walk(object o)
{
return ProcessObject(o).ToList();
}

private static IEnumerable<ObjectWalkerEntity> ProcessObject(object o)
{
if (o == null)
{
// nothing here, just return an empty enumerable object
return new ObjectWalkerEntity[0];
}

// create the list to hold values found in this object
var objectList = new List<ObjectWalkerEntity>();

Type t = o.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{
if (IsGeneric(pi.PropertyType))
{
// Add generic object
var obj = new ObjectWalkerEntity();
obj.PropertyInfo = pi;
obj.Value = pi.GetValue(o, null);
objectList.Add(obj);
}
else
{
// not generic, get the property value and make the recursive call
object value = pi.GetValue(o, null);
// all values returned from the recursive call get
// rolled up into the list created in this call.
objectList.AddRange(ProcessObject(value));
}
}

return objectList.AsReadOnly();
}

private static bool IsGeneric(Type type)
{
return
IsSubclassOfRawGeneric(type, typeof(bool)) ||
IsSubclassOfRawGeneric(type, typeof(string)) ||
IsSubclassOfRawGeneric(type, typeof(int)) ||
IsSubclassOfRawGeneric(type, typeof(UInt16)) ||
IsSubclassOfRawGeneric(type, typeof(UInt32)) ||
IsSubclassOfRawGeneric(type, typeof(UInt64)) ||
IsSubclassOfRawGeneric(type, typeof(DateTime));
}

private static bool IsSubclassOfRawGeneric(Type generic, Type toCheck)
{
while (toCheck != typeof(object))
{
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur)
{
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
}

关于c# - 递归例程获取PropertyInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8095180/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com