当基类是通用的时,如何将派生对象设置为基类变量

时间:2011-12-01 15:39:05

标签: c# generics inheritance

在我的Silverlight 4应用程序中,我正在尝试使用泛型,但还有另一个问题,我希望在stackoverflow-community的帮助下解决:

我有一个树形结构,可以有两种模式,编辑模式,创建树,添加,移动,删除节点等,以及配置模式,用户可以选择树的节点

为了表示树,我为两种模式创建了一个基类,并为每种模式创建了一个派生类。由于编辑模式只能有编辑器节点,配置器模式只能有配置器节点,所以我使基类通用:

public abstract class ServiceModelBase<TRootNodeType>
    where TRootNodeType : ServiceNodeVMBase
{
  public TRootNodeType RootNode
  {
    get { return _rootNode; }
  }
  ...
}

public class ServiceModelConfigurator : ServiceModelBase<ServiceNodeVMConfigurator>
public class ServiceModelEditor : ServiceModelBase<ServiceNodeVMEditor>

ServiceNodeVMConfigurator和ServiceNodeVMEditor都继承自ServiceNodeVMBase

应用程序可以保存并加载保存的数据。装载工作(简称)这样:
1.)在特殊的Datatransferobject中反序列化序列化数据 2.)根据Datatransferobject的类型,创建ServiceModelConfigurator或ServiceModelEditor
3.)触发一个事件,其中包含(与其他人一起)创建的ServiceModel

我创建了一个派生自EventArgs的类,它必须存储ServiceModel。由于这个ServiceModel可以是Editor或Creator,我声明了Property来存储它的baseclasstype:

public class ServiceModelLoadedEventArgs : EventArgs
{
  public ServiceModelBase<ServiceNodeVMBase> ServiceModel;
  ...
}

但不幸的是,我无法将派生的ServiceModelEditor / Configurator分配给EventArgs ServiceModel变量:

ServiceModelLoadedEventArgs args = new ServiceModelLoadedEventArgs();
args.ServiceModel = new ServiceModelEditor();

编译器告诉我,它无法在ServiceModelBase中转换ServiceModelEditor

有人能告诉我,我如何编写EventArgs类的代码,我可以将ServiceModelEditor ServiceModelConfigurator分配给ServiceModel变量?

PS:我想道歉,这只是我的另一个与仿制品相关的问题,但我担心仿制药和我还不是真正的朋友。

2 个答案:

答案 0 :(得分:1)

要使用协方差,您必须声明一个协变接口:

public interface IServiceModelBase<out TRootNode> 
     where TRootNode : ServiceNodeVMBase 
{ 
    TRootNode RootNode { get; }     
} 

public abstract class ServiceModelBase<TRootNode> : IServiceModelBase<TRootNode>
{
    ...
}

public class ServiceModelLoadedEventArgs : EventArgs   
{   
  public IServiceModelBase<ServiceNodeVMBase> ServiceModel { get; set; }  
  ...   
}   

public class ServiceModelEditor : ServiceModelBase<ServiceNodeVMEditor>  

ServiceModelLoadedEventArgs args = new ServiceModelLoadedEventArgs();        
args.ServiceModel = new ServiceModelEditor();

答案 1 :(得分:0)

您可以使用 co-variance

public abstract class ServiceModelBase<out RootNodeType>
     where RootNodeType : ServiceNodeVMBase
{


}