我想我可以做得比看起来简单得多。
我需要最有效的方法来获取对象图中特定类型的所有实例。
我已经开始使用反射来处理对象的属性,寻找这种类型的实例,然后继续处理所有其他复杂的类型和集合。这开始感觉像是一项艰巨的工作,也是一个人过去必须做的事情。因此,在我投入大量的工作和测试之前,我想我会问我是否错过了框架内的快速胜利,或者是否有任何建议让图书馆做这类工作。
我为什么要这么做?我有一种其他人衍生的类型。这种类型具有常见的属性,更重要的是,还有一个特定的属性,用于识别错误,即HasErrors。此类型用于模型的构建。每种型号都不同。有些简单而肤浅,有些复杂而深刻。按照一般规则,每个复杂节点都是一个集合或从该类型派生的自定义类型。我需要一种快速的方法来遍历这些检查所有HasErrors属性的任何实例。任何true的实例都表示模型有错误。
Model
CustomerId (int)
CustomerDetails : MyType
Name (string)
DoB (DateTime)
Addresses (Collection<Address : MyType>)
[Line1 (string)
Line2 (string)]
希望这能说明问题。
如果你想遍历由你的类型组成的整个对象图,你可以让它们都实现这样的接口:
interface IComponent
{
IEnumerable<IComponent> Components { get; }
}
然后使用这个接口遍历整个对象图。如果图形可以包含循环,则必须使用访问顶点的HashSet<IComponent>
之类的方法来防止这种情况。
在实现该接口时,迭代器块可能很有用:
class FamilyMember : IComponent
{
IEnumerable<IComponent> IComponent.Components
{
get
{
if (Father != null)
yield return Father;
if (Mother != null)
yield return Mother;
foreach (var child in Children)
yield return child;
}
}
}
如果您已经有很多类型是对象图的一部分,那么这样做可能会很乏味。如果是这种情况,并且您不介意性能损失,那么使用反射可能对您更好。
这是一个"跳出框框思考"的答案,但我认为你不应该搜索向下树,我认为你应该传播错误向上。
为每个对象提供对其父对象或模型根节点的引用。当对象的HasErrors
属性为true时,它会通过其所有祖先或直接向根向树上发送一条消息,具体取决于您使用的引用类型。
这样,您就可以直接知道模型何时出现错误,并且不需要实现复杂、昂贵且可能毫无结果的自上而下的树搜索。