Reputation: 4782
in my Silverlight 4 application, I am trying to use generics, but there is another problem, that I hope to solve with the help of the stackoverflow-community:
I have a Tree-Structure, that can have two modes, Editor-mode, where the tree is created, nodes added, moved, deleted etc. and a Configurator-mode, where the user can i.e. select nodes of the tree.
To represent the tree, I created a base class for both modes, and a derived class for each mode. As the Editor-mode can only have Editor-Nodes and the Configurator-Mode can only have Configurator-Nodes, I made the baseclass generic:
public abstract class ServiceModelBase<TRootNodeType>
where TRootNodeType : ServiceNodeVMBase
{
public TRootNodeType RootNode
{
get { return _rootNode; }
}
...
}
public class ServiceModelConfigurator : ServiceModelBase<ServiceNodeVMConfigurator>
public class ServiceModelEditor : ServiceModelBase<ServiceNodeVMEditor>
Both ServiceNodeVMConfigurator and ServiceNodeVMEditor inheriting from ServiceNodeVMBase
The application can save and load the saved data. Loading works (in short) this way:
1.) Deserialize the serialized data in a special Datatransferobject.
2.) Depending on the type of the Datatransferobject, creating a ServiceModelConfigurator or ServiceModelEditor
3.) Firing an event, that contains (beside others) the created ServiceModel
I have created a class derived from EventArgs that have to store the ServiceModel. As this ServiceModel can be Editor or Creator, I declared the Property to store it of the baseclasstype:
public class ServiceModelLoadedEventArgs : EventArgs
{
public ServiceModelBase<ServiceNodeVMBase> ServiceModel;
...
}
But unfortunatly, I cannot assign the derived ServiceModelEditor/Configurator to the EventArgs ServiceModel variable:
ServiceModelLoadedEventArgs args = new ServiceModelLoadedEventArgs();
args.ServiceModel = new ServiceModelEditor();
The compiler tells me, that it cannot convert ServiceModelEditor in ServiceModelBase
Can anyone tell me, how I have to write the code for the EventArgs-class that I can assign a ServiceModelEditor or ServiceModelConfigurator to the ServiceModel variable?
PS: I want to apologize that this is just another generics related question from me, but I fear generics and me are not really friends yet.
Upvotes: 1
Views: 435
Reputation: 43046
To use covariance you'll have to declare a covariant interface:
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>
And:
ServiceModelLoadedEventArgs args = new ServiceModelLoadedEventArgs();
args.ServiceModel = new ServiceModelEditor();
Upvotes: 1
Reputation: 49251
You can use co-variance:
public abstract class ServiceModelBase<out RootNodeType>
where RootNodeType : ServiceNodeVMBase
{
}
Upvotes: 0