2011-11-04 184 views
8

使用C#我有一个类,其中包含其他元信息的有向图的根节点。我们称之为Container-Class。该容器可以以两种不同的模式出现,编辑器模式和配置器模式。根据模式,根节点具有不同的类型节点编辑NodeConfig,它们都从相同的子类继承。更改继承属性的类型(到继承类型)

public abstract class NodeBase 
{ 
    string Name { get; set; } 
    ... 
} 

public class NodeEdit : NodeBase ... 
public class NodeConfig : NodeBase ... 

对于容器,我也创建了一个基类,从它继承:

public abstract class ContainerBase 
{ 
    NodeBase Root { get; set; } 
    ... 
} 

当从ContainerBase继承创建编辑器 - 和Configuratorcontainer类,我想成为的类型根 - 财产的具体(从NodeBase继承)类型,如:

public class ContainerEditor : ContainerBase 
{ 
    NodeEditor Root { get; set; } 
    ... 
} 

但我不能改变ContainerBase定义的属性的类型。有没有办法解决这个问题?我可以使用BaseNode型,并且因为类型NodeEditor从类型BaseEditor继承添加NodeEditor的元素像

ContainerEditorInstance.Root = new NodeEditor(); 

,但在集装箱编辑器类,我想明确地只允许的类型根属性为NodeEditor。 我可以在setter中检查这个,并且拒绝所有节点,但是那些NodeEditor类型的,但是我希望这个属性是特定类型的,所以我可以在编译时检测到错误的赋值。

由于提前,
弗兰克

回答

4

你可以重新声明它:

public class ContainerEditor : ContainerBase 
{ 
    public NodeEditor Root { 
    get { return (NodeEditor)base.Root; } 
    set { base.Root = value; } 
    } 
    ... 
} 
+0

嗨,马克,感谢您的回复!我已经尝试过重新宣布,但可能我做错了什么。我测试了你的方法,它工作正常!一般来说,在哪些情况下,应该优先选择泛型还是反义词,还是相同? – Aaginor

+0

当泛型基类必须被使用,即作为一个抽象的返回类型时,这个整体泛型东西造成了严重的问题。所以我给了重新声明一个镜头,因为它似乎不那么侵扰。与“新”和“覆盖”相比,如何重新宣布内部工作?有什么好的文章可以推荐吗?再次感谢! – Aaginor

9

使用泛型:

public abstract class ContainerBase<T> where T:NodeBase 
{ 
    T Root { get; set; } 
    ... 
} 

public class ContainerEditor : ContainerBase<NodeEditor> 
{  
    ... 
} 
+0

嗨布劳,从来没有处理仿制药通常HashSet的和类似用途的旁边。认为这可能是一个与他们合作的好时机! – Aaginor

1

可以使容器底部一般:

public abstract class ContainerBase<TRoot> where TRoot : NodeBase 
{ 
    TRoot Root { get; set; } 
    ... 
} 

在派生类中指定类型:

public class ContainerEditor : ContainerBase<NodeEditor> 
{ 
    ... 
} 
+0

好主意,我会给它一个镜头。 – Aaginor

0

我想这里的一个很好的解决方案将是泛型。所以,你会写是这样的:

public class ContainerEditor<T>:ContainerBase 
{ 
    T Root {get;set;} 
} 
+0

我需要在ContainerBase中声明Root以便能够在不需要知道其编辑器或配置器的函数中访问它。无论如何,泛型听起来像一个好主意,就像Guffa和Blau所示。 – Aaginor