2016-10-17 2 views
2

Я ищу/tring для реализации реализации безопасного типа дерева в C#.в C# для реализации типа безопасного дерева (typeafe node)

Как можно реализовать безопасное дерево типа без использования интерфейсов (которые заставляют повторно реализовывать функциональность дерева по всему месту) и без использования приведений?

У меня есть идея использовать дерево как общий базовый класс, но тогда тип безопасности ушел. Мой текущий подход - это использование дженериков. Но я теряю некоторое преобразование обратно к базовому типу.

Ниже приведен пример сокращения/нерабочий. Идея состоит в том, что возвращаемые узлы поддерживают функции дерева, и в то же время они также поддерживают поведение своих базовых типов. Я мог бы использовать ниже класс без и унаследовать от Node, но затем я потеряю безопасность типа с одной стороны, а также получаю проблемы с наследованием, поскольку узлы уже имеют родительские классы.

Я также играл с расширениями класса, но у меня нет ничего, что близко к возможному решению.

Думаю, мне нужен небольшой намек на то, как продолжить. Заранее спасибо.

public class Node<T> // . 
{ 
    public Node<T> parent; 
    public List<Node<T>> children; 

    protected Node() 
    { 
     children = new List<Node<T>>(); 
     parent = null; 
    } 
    protected Node(Node<T> parent) 
     : this() 
    { 

     this.parent = parent; 
     parent.addChildren(this); 
    } 


    protected void addChildren(Node<T> child) 
    { 
     children.Add(child); 
    } 
    public Node<T> getRoot() // returns root node 
    public List<Node<T>> flatten() // return 1d-list of all nodes. 

} 
+0

Может ли тип T меняться для каждого узла в дереве? Или это всегда будет одинаковым во всем дереве? – Soukai

+0

Нет (только подклассы). Но я хотел бы использовать ту же реализацию дерева для другого T. – James

ответ

0

Вот типобезопасный реализация дерева:

public class Tree<T> : List<Tree<T>> 
{ 
    public T Value { get; set; } 
} 

Да, это так. Просто.

Конечно, вы можете добавить конструктор или два, и сделать свойство Value доступным только для чтения, чтобы сделать его еще более дружественным к ООП. И вы можете легко добавить свойство Parent.

+0

Лучшие идеи - это те, кто очевиден. :-) – James

0

У меня есть идея использования дерева в качестве общего базового класса, но типа безопасности ушла. Мой текущий подход - это использование дженериков. Но я теряю некоторое преобразование обратно к базовому типу.

Тогда тяготы общего типа для базового типа:

public class Node<T> where T: BaseType { ... } 

Теперь вы можете создать любое дерево типа Node<MyDerivedType>, пока MyDerivedType происходит от BaseType.

На стороне нет, я бы рассмотреть вопрос об изменении следующих в своей реализации:

  1. Children должен быть свойством, не не подвергать поле, если его ЧТЕНИЯ. Кроме того, вы не должны раскрывать его как List; что позволит любому добавить или удалить узлы, которые могут нарушить инварианты, принятые в вашей реализации. Возвратить IEnumerable<T> вместо:

    private readonly List<T> children; 
    public IEnumerable<T> Children => children.Select(c => c); 
    

    Вы можете вернуть children непосредственно в его неявно конвертируются в IEnumerable<T>; проблема в том, что любой может просто вернуть его обратно на List<T> и изменить его. Проецирование защищает вас от этого преобразования.

  2. То же самое происходит с Flatten (первый f должен быть капитализирован кстати). Рассмотрите возможность возврата IEnumerable<T>.

 Смежные вопросы

  • Нет связанных вопросов^_^