2015-08-20 4 views
0

Я хочу добиться следующего. Словарь вроде структуры данных, который я инициализирую с помощью var m = new MultiMap<string, int, bool>();, а затем я должен иметь доступ к нему, используя m[string1] или m[int1], а string1 - это строка, а int1 - это int. Конечно, если мне нужно добавить значение, мне нужно будет сделать что-то вроде этого m.add(string2, int2, bool2), так что оба ключа не равны нулю. Есть ли что-то подобное уже имеющееся? Спасибо и приветствую!Словарь с несколькими ключевыми типами

+3

List <Кортеж >() должны делать то, что вы хотите. Вы можете LINQ выбрать/where клаузулы для Item1 (String), Item2 (Int32) и Item3 (Boolean). –

+0

См. Http://stackoverflow.com/q/689940/2076784 и http://stackoverflow.com/q/1171812/2076784. – gpaoli

+0

Я бы просто пошел на реализацию с двумя базовыми словарями, если у вас нет ограничений памяти. –

ответ

0

У вас просто не может быть двух ключей для предмета. Когда вы добавляете элемент в словарь с ключом и значением, внутренний хэш-код этого ключа генерируется путем вызова метода GetHashCode этого ключа, и значение сохраняется с этим хеш-кодом. Поэтому, если вы можете каким-то образом сопоставить свои строки и int ключи с тем же хэш-кодом, то только вы сможете получить доступ к своему значению с помощью любого из одного ключа. Поэтому, если это возможно, то лучше всего реализовать класс Key с тремя конструкциями, один для строки, один для int и один для обоих. Затем реализуем IEqualityComparer, передайте его в конструкцию словаря.

0

Вы можете свернуть свой собственный довольно быстро, так что здесь является частично законченный класс: (. Я думал, что я дам вам немного форы, и вы можете взять его здесь)

public class MultiKeyDictionary<T> 
{ 
    private Dictionary<int, T> _indexDictionary = new Dictionary<int, T>(); 
    private Dictionary<string, T> _keyDictionary = new Dictionary<string, T>(); 

    public int Count 
    { 
     get { return _indexDictionary.Count; } 
    } 

    public T this[string key] 
    { 
     get 
     { 
      T result; 
      if (!TryGetValue(key, out result)) 
      { 
       throw new IndexOutOfRangeException(); 
      } 
      return result; 
     } 
     set 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public T this[int key] 
    { 
     get 
     { 
      throw new NotImplementedException(); 
     } 
     set 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public void Add(int index, string key, T value) 
    { 
     _indexDictionary.Add(index, value); 
     _keyDictionary.Add(key, value); 
    } 

    public void Clear() 
    { 
     _indexDictionary.Clear(); 
     _keyDictionary.Clear(); 
    } 

    public bool Contains(T item) 
    { 
     return _indexDictionary.ContainsValue(item); 
    } 

    public bool Remove(string key) 
    { 
     throw new NotImplementedException(); 
    } 

    public bool Remove(int key) 
    { 
     throw new NotImplementedException(); 
    } 


    public bool TryGetValue(string key, out T value) 
    { 
     var result = _keyDictionary.TryGetValue(key, out value); 

     return result; 
    } 

    public bool TryGetValue(int key, out T value) 
    { 
     var result = _indexDictionary.TryGetValue(key, out value); 

     return result; 
    } 
} 

После этого вы можете:

var m = new MultiKeyDictionary<bool>(); 
m.add(int2, string2, bool2) 

и доступ к ней нравится:

var mystring = m[string1]; 
var myint = m[int1]; 

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

bool value; 
if (m.TryGetValue(string1, out value)) 
{ 
    // value exists, I don't get an IndexOutOfRangeException 
} 

bool value; 
if (m.TryGetValue(int1, out value)) 
{ 
    // value exists, I don't get an IndexOutOfRangeException 
}