c# - 在对象图中查找所有类型的实例
问题描述
可以说我有以下对象图
Parent : BaseEntity
string1 SimpleString
Middle Middle
List<Child> Children (3)
Middle : BaseEntity
string NormalStr
int NiceInt
RandomClass Ignore
Child : BaseEntity
string ChildString
Parent Parent
在这个例子中,我想要一种方法将我的 Parent 作为输入并返回一个平面列表 {Parent,Middle,Child1,Child2,Child3}。它应该适用于任何类型的对象图。
我试图通过反射和递归到达那里。我遇到的问题是 Parent 和 Child 之间的循环引用,我最终陷入了无限循环。
我该如何防止这种情况?我似乎无法让任何“已经看到”的机制起作用。
这是我到目前为止得到的。它可以在没有收集部分的情况下工作,但那部分非常重要......
public void TraverseThroughProperties(object myObject)
{
foreach (var prop in myObject.GetType().GetProperties())
{
var instance = prop.GetValue(myObject);
if (instance is BaseEntity myBase)
TraverseThroughProperties(instance);
if (instance is ICollection collection)
{
foreach (var item in collection.OfType<BaseEntity>())
TraverseThroughProperties(item);
}
// Do something with myObject + prop
}
}
解决方案
如果我正确理解了这个问题,我想最简单的方法是保留HashSet
您访问过的类型。
public static void TraverseThroughProperties(object myObject, HashSet<Type> hashset = null)
{
hashset ??= new HashSet<Type>();
if (hashset.Contains(myObject.GetType()))
return;
hashset.Add(myObject.GetType());
...
注意:这可能不是最优的,因为它会拒绝相同的类型。另一种方法是保留访问的父子类型的元组。但是,这可能再次过滤超出预期。
public static void TraverseThroughProperties(object myObject, object parent, HashSet<(Type,Type)> hashset = null)
{
hashset ??= new HashSet<(Type,Type)>();
...
另一种方法是散列实际参考。这将跟踪引用,或者再次跟踪父子引用
public static void TraverseThroughProperties(object myObject, HashSet<object> hashset = null)
{
hashset ??= new HashSet<object>();
if (hashset.Contains(myObject))
return;
hashset.Add(myObject);
虽然仍然可能不是您正在寻找和过滤的东西。然后这成为一个概念问题,您可能需要重新考虑您在做什么以及为什么。
推荐阅读
- corda - 如何在 Corda 项目的 CLI 中传递对象
- angular - Angular 8 多个 mat-checkbox 需要验证
- django - Django模板 - 如何在给定索引号(由迭代器生成)的表单(上下文)中访问表单
- python - celery 任务中的数据库已过时
- .net-core - .Net Core 2.0 返回 BadRequestObjectResult 导致 Newtonsoft.Json.JsonSerializationException:检测到自引用循环
- sql - 从行和列中的 Json 数组中获取数据
- android - MultiAutoCompleteTextView android限制用户多次选择相同的值
- c++ - 在类中使用随机生成器时的性能问题
- python - 访问主页时出现 Pythonanywhere 错误
- android - 如何从 Kotlin 中的内部类 [AsyncTask] 访问扩展功能?