В C # 4 это можно сделать с помощью универсальной ковариации интерфейса:
public class ContainerBase<NodeType, ObjectType> : IContainerBase<NodeType, ObjectType>
where NodeType : NodeBase<ObjectType> where ObjectType : ObjectBase {
}
public abstract class NodeBase<T> where T : ObjectBase {
IContainerBase<NodeBase<T>, T> container;
public NodeBase(IContainerBase<NodeBase<T>, T> owner) {
container = owner;
}
}
public class ContainerNormal : ContainerBase<NodeNormal, ObjectNormal> {
}
public interface IContainerBase<out NodeType, ObjectType>
where NodeType : NodeBase<ObjectType> where ObjectType : ObjectBase {
}
public class NodeNormal : NodeBase<ObjectNormal> {
//This doesn't work
public NodeNormal(ContainerNormal owner) : base(owner) { }
}
public class ObjectNormal : ObjectBase {}
public class ObjectBase{}
Конечно, это будет работать, только если ваш интерфейс IContainerBase может избежать использования каких-либо функций, которые бы принимали NodeType
в качестве ввода. Например, это будет работать:
public interface IContainerBase<out NodeType, ObjectType>
where NodeType : NodeBase<ObjectType> where ObjectType : ObjectBase
{
NodeType NodeTypeProp {get;}
}
... но это не так:
public interface IContainerBase<out NodeType, ObjectType>
where NodeType : NodeBase<ObjectType> where ObjectType : ObjectBase
{
NodeType NodeTypeProp {get;set;} // "set" not allowed on "out" type
}
Еще одно замечание: вы заметили, как мне пришлось называть свойство «NodeTypeProp» вместо «NodeType»? Это потому, что мы не следуем соглашениям об именах C #. Вы должны использовать префикс "T" для имен обобщенных типов:
public interface IContainerBase<out TNodeType, TObjectType>
where TNodeType : NodeBase<TObjectType> where TObjectType : ObjectBase