在我的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:我想道歉,这只是我的另一个与仿制品相关的问题,但我担心仿制药和我还不是真正的朋友。答案 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
{
}