Я не знаю C #, но Java-программисты иногда тоже сталкиваются с этой проблемой.
Оглядываясь на другие источники C #, я думаю, что вы можете делать то, что вы хотите (с небольшой потерей безопасности типов) с помощью:
public class Entity<T>
{
public Entity<P> Parent
where P : Entity<Entity<T>>
{ get; private set; }
//
//
//
public Entity(Entity<P> parent)
where P : Entity<Entity<T>>
{
this.Parent = parent;
}
}
Ответ Java будет включать ? extends Entity<T>
. Основная проблема заключается в том, что, хотя Molecule
является Entity<Atom>
, компилятор не может знать, что Molecule
также является Entity<Entity<Particle>>
. В конце концов, предположим, что Entity
вел список детей и имел разумный метод addChild(T child)
. Тогда компилятор захочет убедиться, что вы только добавили Atom
s как дочерние элементы молекул. Но если Molecule
является Entity<Entity<Particle>>
, то ничто не помешает вам сделать:
Entity<Entity<Particle>> downcast = myMolecule;
downcast.addChild(myNonAtomParticleBasedEntity);
Правильное полностью безопасное для типов решение для этого шаблона включает self types , которого нет в Java и C #. Шаблон Java Foo<F extends Foo<F>>
( и его эквивалент C # ) близок, но работать с ним очень скользко. За исключением этого, объявление-время сделает этот шаблон чище.