.NET基类库中是否存在允许使用重复键的字典类?我找到的唯一解决方案是创建,例如,一个类:

Dictionary<string, List<object>>

但实际上用起来很烦人。在Java中,我相信MultiMap可以实现这一点,但在. net中找不到类似的东西。


当前回答

回答了最初的问题。像Dictionary<string, List<object>>这样的东西是在Code项目中一个名为MultiMap的类中实现的。

你可以在下面的链接中找到更多信息: http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx

其他回答

我刚刚遇到了PowerCollections库,其中包括一个名为MultiDictionary的类。它巧妙地包装了这种类型的功能。

当使用List<KeyValuePair<string, object>>选项时,你可以使用LINQ来进行搜索:

List<KeyValuePair<string, object>> myList = new List<KeyValuePair<string, object>>();
//fill it here
var q = from a in myList Where a.Key.Equals("somevalue") Select a.Value
if(q.Count() > 0){ //you've got your value }

你可以定义一个方法来构建复合字符串键 在任何你想要使用字典的地方,你都必须使用这个方法来构建你的键 例如:

private string keyBuilder(int key1, int key2)
{
    return string.Format("{0}/{1}", key1, key2);
}

使用:

myDict.ContainsKey(keyBuilder(key1, key2))

“滚动您自己的”版本的字典,允许“重复键”条目,这很容易。下面是一个粗略的简单实现。您可能需要考虑添加对dictionary <T>的基本大部分(如果不是全部)的支持。

public class MultiMap<TKey,TValue>
{
    private readonly Dictionary<TKey,IList<TValue>> storage;

    public MultiMap()
    {
        storage = new Dictionary<TKey,IList<TValue>>();
    }

    public void Add(TKey key, TValue value)
    {
        if (!storage.ContainsKey(key)) storage.Add(key, new List<TValue>());
        storage[key].Add(value);
    }

    public IEnumerable<TKey> Keys
    {
        get { return storage.Keys; }
    }

    public bool ContainsKey(TKey key)
    {
        return storage.ContainsKey(key);
    }

    public IList<TValue> this[TKey key]
    {
        get
        {
            if (!storage.ContainsKey(key))
                throw new KeyNotFoundException(
                    string.Format(
                        "The given key {0} was not found in the collection.", key));
            return storage[key];
        }
    }
}

一个关于如何使用它的简单例子:

const string key = "supported_encodings";
var map = new MultiMap<string,Encoding>();
map.Add(key, Encoding.ASCII);
map.Add(key, Encoding.UTF8);
map.Add(key, Encoding.Unicode);

foreach (var existingKey in map.Keys)
{
    var values = map[existingKey];
    Console.WriteLine(string.Join(",", values));
}

我将@Hector Correa的答案更改为具有泛型类型的扩展,并添加了一个自定义TryGetValue。

  public static class ListWithDuplicateExtensions
  {
    public static void Add<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
    {
      var element = new KeyValuePair<TKey, TValue>(key, value);
      collection.Add(element);
    }

    public static int TryGetValue<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> collection, TKey key, out IEnumerable<TValue> values)
    {
      values = collection.Where(pair => pair.Key.Equals(key)).Select(pair => pair.Value);
      return values.Count();
    }
  }