Reputation: 2292
I'm attempting to override a base property like so:
public class Node {}
public class SubNode : Node { }
public class NodeViewModel<T> where T : Node
{
public virtual T Data { get; set; }
}
public class SubNodeViewModel : NodeViewModel<SubNode>
{
public override SubNode Data { get; set; }
}
...
List<NodeViewModel<Node>> l = new List<NodeViewModel<Node>>();
l.Add(new SubNodeViewModel()); // Cannot convert from SubNodeViewModel to NodeViewModel<Node>
...
I think I must be misunderstanding a fundamental of inheritance. Why am I not able to do this?
I guess I'm confused as to why this works:
Node node;
SubNode subnode;
node = subnode; // I work just fine!
But not this:
NodeViewModel<Node> node;
SubNodeViewModel subnode;
node = subnode; // I don't work. Also, I hate you!
Upvotes: 1
Views: 55
Reputation: 437356
You are not able to do this because NodeViewModel<T>
is not covariant on its type argument T
: NodeViewModel<Node>
is not the "base class" of NodeViewModel<SubNode>
, even if Node
is the base of SubNode
. Technically this has nothing to do with inheritance.
If you want to have all kinds of NodeViewModel
in the same list the only way to do that is by using a common interface or base class as the type argument of the list.
Upvotes: 4
Reputation: 144136
The error occurs because your NodeViewModel<T>
class is not covariant. Whether you can do this depends on the operations you need to support, but for the code in your question you can create an interface:
public interface INodeViewModel<out T> where T : Node
{
T Data { get; }
}
then implement it
public NodeViewModel<T> : INodeViewModel<T> where T : Node { ... }
then change the type of the items in l
:
List<INodeViewModel<Node>> l = new List<INodeViewModel<Node>>();
Upvotes: 2