В C# У меня есть навязчивым древовидную структуру, которая выглядит следующим образом:Как сделать интрузивный древовидный класс в C# использовать дженерики?
public abstract class Node
{
Container parent;
Node nextNode;
Node previousNode;
public abstract class Container : Node
{
Node firstChild;
Node lastChild;
}
}
Различные объекты, которые могут быть добавлены к дереву наследоваться от обоих Node
или Container
в зависимости от того, могут ли они иметь детей или нет.
Посредством создания класса Container
внутренний класс означает, что он может получить доступ к частным членам в Node
для управления списком детей в контейнере.
Это все хорошо и хорошо. Но теперь я хочу сделать его общим, чтобы я мог повторно использовать его при сохранении безопасности типов - в основном, перемещая всю функциональность дерева в общий класс выше узла, а другой между узлами и контейнером. Вот грубый дизайн того, что я пытаюсь сделать:
public abstract class GenericNode<Node, Container>
where Node : GenericNode<Node, Container>
where Container : GenericNode<Node, Container>.GenericContainer
{
Container parent;
Node nextNode;
Node previousNode;
public abstract class GenericContainer : Node
{
Node firstChild;
Node lastChild;
}
}
Что, конечно, не работает, потому что вы не можете сделать GenericContainer
наследовать от Node
(ошибки компилятора CS0689). Даже если я откажусь от внутреннего требования к классу (скажем, используя internal
и просто будучи осторожным в своей собственной библиотеке), я все еще не могу понять дизайн, который не сталкивается с той же проблемой (и ошибкой).
(Я не думал, что мне нужно, но просто для того, чтобы его прописать: Я не пытаюсь «исправить» ошибку компиляции, и я не ищу простой реализации дерева. дизайн вопрос.)
Итак, теперь я немного в тупике. Есть ли у кого-нибудь лучшие идеи о том, как это сделать?
Редактировать: Не забудьте взглянуть на this answer, что является еще одним ударом по дизайну, который пытается использовать методы расширения, чтобы избежать проблемы «инъекции» класса в иерархию наследования (но, к сожалению, не полностью Работа).
Да, ошибка компиляции из-за вашего наименования. Просто назовите параметры типа TNode и TContainer, и он просто компилирует ... –
@Claus: Нет, это не так, и нет, это не так (причина, по которой ваш ответ компилируется, заключается в том, что вы изменили то, что наследует GenericContainer). –
Да, конечно. Но я все же хотел указать, почему у вас возникла ошибка CS0689, потому что у вас были конфликтующие имена. Так лучше, если вы оставили такие проблемы из вопроса;) –