Я создаю древовидную структуру на основе класса AbstractNode. Класс AbstractNode имеет универсальное свойство коллекции, которое содержит его дочерние узлы. См. пример кода ниже.
Есть ли какой-то способ, возможно, с помощью дженериков, чтобы я мог ограничить конкретную версию AbstractNode, чтобы разрешить только один тип дочернего узла? См. приведенный ниже код для ConcreteNodeA, где его свойство ChildNodes представляет собой набор ConcreteNodeB, а не AbstractNode. Это, конечно, не компилируется, но мне интересно, есть ли какой-то другой метод, который я мог бы использовать для достижения такого же эффекта.
Конечно, все будет работать, если свойство коллекции ChildNodes всегда имеет тип AbstractNode, но я пытаюсь внедрить в свои классы некоторую логику в отношении того, какие узлы должны быть потомки других узлов. Кроме того, при ссылке на свойство ChildNodes было бы неплохо, если бы мне не приходилось преобразовывать коллекцию в коллекцию того типа, который, как я знаю, должен быть.
public abstract class AbstractNode
{
public abstract NodeCollection<AbstractNode> ChildNodes
{
get;
set;
}
}
public class ConcreteNodeA : AbstractNode
{
//THIS DOES NOT COMPLILE
//Error 1 'ConcreteNodeA.ChildNodes': type must be 'NodeCollection<AbstractNode>'
//to match overridden member 'AbstractNode.ChildNodes'
public override NodeCollection<ConcreteNodeB> ChildNodes
{
get;
set;
}
}
public class ConcreteNodeB : AbstractNode
{
public override NodeCollection<AbstractNode> ChildNodes
{
get;
set;
}
}
public class NodeCollection<T> : BindingList<T>
{
//add extra events here that notify what nodes were added, removed, or changed
}
Обновить
Хорошо, я думаю, что понял, что хочу сделать, но я хотел бы знать, думает ли кто-нибудь, что это «плохо» или «забавно пахнет» и почему. Вместо того, чтобы мои узлы имели свойство коллекции ChildNodes, я думаю сделать каждый узел фактической коллекцией. Итак, моя древовидная структура на самом деле будет просто серией коллекций коллекций. Затем мои абстрактные классы Node будут использовать различные ограничения на дженерик для управления типами подузлов, которые он может иметь.
Имеет ли это смысл? Есть ли причина, по которой я не хотел бы этого делать? Я никогда раньше не использовал дженерики ни в одном из своих классов, поэтому не уверен, что что-то упускаю из виду.
public interface INode
{
}
public abstract class AbsNode<T> : BindingList<T>, INode where T : INode
{
}
public abstract class AbsNodeA<T> : AbsNode<T> where T : AbsSubNodeA
{
}
public abstract class ConcreteNodeA : AbsNodeA<AbsSubNodeA>
{
}
public abstract class AbsSubNodeA : INode
{
}
public class ConcreteSubNodeA :AbsSubNodeA
{
}
public class ConcreteSubNodeB :AbsSubNodeA
{
}