Как создать полную универсальную структуру данных типа TreeView - PullRequest
7 голосов
/ 02 июня 2010

Я хочу создать полностью общую древовидную структуру. что-то вроде этого:

public class TreeView<T, K, L>
{
    public T source;
    public K parent;
    public List<L> children;
}

Как вы можете видеть в этом источнике класса, у родителя, а также у потомков, все имеют разные общие типы данных. Также я хочу, чтобы у моего дерева было неограниченное количество уровней (не только 3). таким образом, когда я хочу работать с моими узлами в коде, все они будут строго типизированы. не только объекты, которые мне нужны, чтобы преобразовать их в их первоначальный тип.

возможно ли создать такую ​​структуру в c #, древовидную структуру, в которой все его узлы строго типизированы?

спасибо

Ответы [ 3 ]

2 голосов
/ 08 июня 2010

Это большая проблема с древовидными структурами данных. Легко определить однородные деревья, но в реальном мире деревья часто состоят из разнородных типов объектов. Хорошим примером этого является файловая система, в которой дерево содержит диски, папки и файлы.

Вы можете создать безопасное дерево типов, только если точно знаете форму дерева во время компиляции. Конечно, это исключает все случаи использования деревьев в реальном мире.

2 голосов
/ 02 июня 2010

Что ж, кроме дерева, у вас будут некоторые базовые данные. Например, дерево каталогов. Атрибутами каталога являются его имя и список дочерних каталогов. Мы начнем с определения общего TreeItem.

public class TreeItem<T> {
  public TreeItem() {
    Children = new List<TreeItem<T>>();
  }

  public void AddChild(T data) {
    Children.Add(new TreeItem<T>{Data = data, Parent = this});
  }

  public List<TreeItem<T>> Children{get;set;}
  public TreeItem<T> Parent {get;set;}
  public T Data {get;set;}
}

Итак, простое дерево каталогов - это просто TreeItem<string>:

* +1007 *

Это создаст дерево вроде этого:

root
|- child1
|- child2
|- child3

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

1 голос
/ 02 июня 2010

После прочтения Игоря ответьте и ваш комментарий и можете просто сказать, что это невозможно. Все, что вы можете сделать, это использовать в качестве T некоторый базовый тип, общий для всех классов, например, базовый класс или интерфейс.

Но если вам нужен где-то в вашем коде конкретный тип, вам нужно привести его, что может привести к некоторой структуре if-return или if-else-if, например:

SpecificType specType = commonType as SpecificType;
if(specType != null)
{
    //Do something...
    return;
}

AnotherSpecifcType specType2 = commonType as AnotherSpecifcType;
if(specType2 != null)
{
    //Do something...
    return;
}

Но это все, что вы можете сделать.

...