在我的应用程序中,我有一个树状的数据结构。节点属于X类。我有另一个类Y,它是来自X的派生。最后,我需要在整个树结构中将类型X中的节点“转换/更改”为类型Y.
是否有一种简单的方法可以执行此操作,还是必须解析整个树,通过使用类型Y实例化每个节点来重新创建它?
提前致谢,
弗兰克
答案 0 :(得分:2)
是的,您必须遍历整个树并重新创建所有节点。
这使得重新考虑导致这种情况的设计成为一个好主意。
答案 1 :(得分:1)
对象的实际类型在构造时确定,之后无法更改。所以不,没有别的办法。
答案 2 :(得分:0)
更改对象的类型通常是一个很大的代码味道。如果这是必需的,因为对象行为的某些部分应该更改,请查看Strategy Design Pattern。
但无论如何,你通常必须遍历整个树来改变每个节点上的策略。我真的所有对象应该改变行为,你也可以考虑与Flyweight Design Pattern的组合。但正如已经提到的,信息太少,不能在这里给出好的建议。
答案 3 :(得分:0)
也许implicit或explicit操作员可以帮助您,但我认为一些糟糕的设计导致了这一点:
public static implicit operator MyTypeB( MyTypeA a ) {
MyTypeB b = new MyTypeB();
// copy all a properties
return b;
}
人们说你需要循环并重新创建所有节点,但这样所有节点都可以用作不同类型的节点,因为它们可以在需要时进行重新创建。
但请注意,如果某些数据丢失,则不应使用强制转换操作符重载。
严重的是,这一切都导致您假设您缺少这些节点类型的接口,并且该集合应该是此接口类型的集合。
答案 4 :(得分:0)
因为还没有人指出这一点......
如果您将对象创建为Y
,则可以将其转换为X
,然后再次转回Y
,但创建为X
的对象无法转换为{ {1}}。这只是基本的OO行为。
这意味着如果您将数据源创建为Y
的分层列表,则可以将它们转换为Y
,然后在适合时返回X
。
实际上,如果您使用的是Linq,则在Enumerable类上有一个名为Cast()的扩展方法。您可以像这样使用它:
Y
您还没有提到您正在使用的内容(WinForms / WPF / Silverlight / ASP.NET),但是WPF有一个HierarchicalDataTemplate,您可以绑定到类似节点的列表(即列表中的每个项目都可以有子项)。使用上面的public class Animal { }
public class Dog : Animal { }
List<Dog> dogs = new List<Dog>();
List<Animal> animals = dogs.Cast<Animal>().ToList();
这样的东西可以很好地工作。
当然,这并不意味着您不应该检查您的代码,看看这是否真的是最好的方法(正如其他人所说的那样)。