Лучшая реализация для структуры данных пары ключевых значений?

Итак, я немного зациклился на С# в последнее время, и все общие коллекции меня немного смутили. Скажем, я хотел представить структуру данных, где глава дерева была ключевой парой значений, а затем есть один необязательный список пар значений ключа ниже (но не более уровней, чем эти). Будет ли это подходящим?

public class TokenTree
{
    public TokenTree()
    {
        /* I must admit to not fully understanding this,
         * I got it from msdn. As far as I can tell, IDictionary is an
         * interface, and Dictionary is the default implementation of
         * that interface, right?
         */
        SubPairs = new Dictionary<string, string>();
    }

    public string Key;
    public string Value;
    public IDictionary<string, string> SubPairs;
}

Это всего лишь простой шунт для передачи данных.

Ответ 1

Существует фактический тип данных, называемый KeyValuePair, используйте этот

KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");

Ответ 2

Одна возможная вещь, которую вы можете сделать, это использовать объект Dictionary прямо из коробки, а затем просто расширить его своими собственными модификациями:

public class TokenTree : Dictionary<string, string>
{
    public IDictionary<string, string> SubPairs;
}

Это дает вам преимущество в том, что вам не нужно применять правила IDictionary для вашего ключа (например, уникальность ключа и т.д.).

И вы поняли концепцию конструктора:)

Ответ 3

Я думаю, что вы могли бы после (как буквальная реализация вашего вопроса):

pubic class TokenTree
{
    public TokenTree()
    {
        tree = new Dictionary<string, IDictionary<string,string>>();
    }

    IDictionary<string, IDictionary<string, string>> tree; 
}

Вы действительно сказали "список" значений ключа в своем вопросе, чтобы вы могли поменять внутренний IDictionary на:

IList<KeyValuePair<string, string>> 

Ответ 4

Существует встроенный тип KeyValuePair. На самом деле, это то, что IDictionary дает вам доступ к тому, когда вы его итерации.

Кроме того, эта структура вряд ли является деревом, поиск более представительного имени может быть хорошим упражнением.

Ответ 5

Только одна вещь, чтобы добавить к этому (хотя я думаю, что вы уже ответили на свой вопрос другими). В интересах расширяемости (поскольку мы все знаем, что это произойдет в какой-то момент), вы можете захотеть проверить Composite Pattern Это идеальное решение для работая с "Tree-Like Structures".

Как я уже сказал, я знаю, что вы ожидаете только одного под-уровня, но это действительно может быть полезно для вас, если позже вам нужно расширить ^ _ ^

Ответ 6

@Jay Mooney: Общий класс Dictionary в .NET на самом деле является хеш-таблицей, только с фиксированными типами.

Код, который вы показали, не должен убеждать кого-либо использовать Hashtable вместо словаря, поскольку обе части кода могут использоваться для обоих типов.

Для хэш-таблицы:

foreach(object key in h.keys)
{
     string keyAsString = key.ToString(); // btw, this is unnecessary
     string valAsString = h[key].ToString();

     System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString);
}

Для словаря:

foreach(string key in d.keys)
{
     string valAsString = d[key].ToString();

     System.Diagnostics.Debug.WriteLine(key + " " + valAsString);
}

И точно так же для другого с KeyValuePair, просто используйте не-общую версию для Hashtable и общую версию для словаря.

Итак, это так же просто, но Hashtable использует Object как для ключа, так и для значения, что означает, что вы будете вводить все типы значений, и у вас нет безопасности типов, а словарь использует общие типы и, следовательно, лучше.

Ответ 7

Класс словаря - это именно то, что вы хотите, правильно.

Вы можете объявить поле непосредственно как словарь, а не IDictionary, но это зависит от вас.

Ответ 8

Используйте что-то вроде этого:

class Tree < T > : Dictionary < T, IList< Tree < T > > >  
{  
}  

Это уродливо, но я думаю, что это даст вам то, что вы хотите. Слишком плохо KeyValuePair запечатан.