C# 从基类对象创建派生类对象

C# 从基类对象创建派生类对象,c#,architecture,tree,C#,Architecture,Tree,在我的应用程序中,我有一个树状的数据结构。节点属于X类。我有另一个Y类,它是从X派生的。最终,我需要在整个树结构中将节点从X类型“转换/更改”为Y类型 有没有一种简单的方法可以做到这一点,或者我必须解析整个树,通过用Y类型实例化每个节点来重新创建它 提前感谢, 坦率的 伊迪丝说:谢谢你的回答!我试图解释,为什么我需要这种行为: 让我们想象一下,我们是一个餐饮服务商。我们想在一棵树中为我们的投资组合建模。一个节点可以是“汤”,我们提供土豆汤、番茄汤和面条汤——每个节点都是“汤”节点的子节点。完成建

在我的应用程序中,我有一个树状的数据结构。节点属于X类。我有另一个Y类,它是从X派生的。最终,我需要在整个树结构中将节点从X类型“转换/更改”为Y类型

有没有一种简单的方法可以做到这一点,或者我必须解析整个树,通过用Y类型实例化每个节点来重新创建它

提前感谢,
坦率的

伊迪丝说:谢谢你的回答!我试图解释,为什么我需要这种行为: 让我们想象一下,我们是一个餐饮服务商。我们想在一棵树中为我们的投资组合建模。一个节点可以是“汤”,我们提供土豆汤、番茄汤和面条汤——每个节点都是“汤”节点的子节点。完成建模后,我们将树呈现给选择“基本餐饮服务”的客户。这意味着她可以选择一种汤作为晚餐。

对于我的基础模型,这意味着当餐饮服务商创建投资组合时,我需要一个额外的字段“IsSelected”,我不需要这个字段。因此,我想从类X中派生类Y,并添加一个字段。

对象的实际类型是在构造时确定的,以后不能更改。因此,没有其他方法。

是的,您必须遍历整个树并重新创建所有节点


因此,重新考虑导致这种情况的设计是一个好主意。

更改对象的类型通常是一种巨大的代码气味。如果因为对象行为的某些部分应该改变而需要这样做,请查看

但无论如何,您通常必须遍历整个树才能更改每个节点上的策略。如果真的所有对象都应该改变行为,您还可以考虑与。但如前所述,这里的信息太少,无法给出好的建议。

也许或operator cast可以帮助您,但我认为一些糟糕的设计导致了这一点:

public static implicit operator MyTypeB( MyTypeA a ) {
  MyTypeB b = new MyTypeB();
  // copy all a properties
  return b;
}
人们说您需要循环并重新创建所有节点,但通过这种方式,所有节点都可以用作不同类型的节点,因为它们在需要时进行重新创建工作

但请注意,如果某些数据丢失,则不应使用强制转换运算符重载


严重的是,这一切都导致了这样一种假设,即您缺少这些节点类型的接口,并且集合应该是这种接口类型的集合。

因为还没有人指出这一点

如果将对象创建为
Y
,则可以将其强制转换为
X
,然后再返回到
Y
,但创建为
X
的对象不能强制转换为
Y
。这只是基本的OO行为

这意味着,如果将数据源创建为
Y
的分层列表,则可以将它们转换为
X
,然后在合适的时候返回到
Y

事实上,如果您使用的是Linq,那么在可枚举类上会调用一个扩展方法。您可以这样使用它:

public class Animal {   }

public class Dog : Animal {   }

List<Dog> dogs = new List<Dog>();
List<Animal> animals = dogs.Cast<Animal>().ToList();
公共类动物{}
公营狗:动物{}
列表狗=新列表();
列出动物=狗.Cast().ToList();
您没有提到您正在使用什么(WinForms/WPF/Silverlight/ASP.NET),但是WPF有一个hierarchycaldatatemplate,您可以绑定到一个类似节点的列表(即列表中的每个项都可以有子项)。在上面的
Cast()
中使用类似的方法应该可以很好地工作


当然,这并不意味着你不应该检查你的代码,看看这是否是最好的方法(其他人也说过)。

你的问题不是很清楚。你能提供一些背景资料吗?你为什么要这样做?是的,我在设计中添加了一层。当我进入“配置”模式时,我会相应地交换层。