“词典”与键作为存储元素的一部分?

时间:2010-09-16 16:03:22

标签: c# dictionary

好像我忘记了一个类型名称...我脑子里的东西一直告诉我,我偶然发现了一个基本上使用用户定义的Comparer进行查找的字典。但我在某种程度上找不到.Net的深度了。

由于我不知道如何在不描述可能的实现的情况下描述我正在寻找的内容,我还将举例说明我不想做的事情。

我基本上正在寻找一种方法来实现以下(伪代码):

class CustomId
{
   // [...]
}
class Element
{
   CustomId id;
}
Container<CustomId, Element> myContainer = new Container(myCustomComparer)
myContainer.Add(new Element()) // No key specified
myElement = myContainer[new CustomId(...)]; // Retrieval with custom id

也许这在技术上不是一本字典,但我希望这个想法很清楚。基本上,键是存储元素的一部分。

3 个答案:

答案 0 :(得分:12)

我认为您正在寻找KeyedCollection<TKey, TItem>。创建一个继承自此类的类,并覆盖GetKeyForItem()方法。

答案 1 :(得分:2)

实际上很容易。你只需要继承KeyedCollection<TKey, TItem>

public class ElementCollection : KeyedCollection<CustomId, Element>
{
    public override CustomId GetKeyForItem(Element element)
    {
        return element.id;
    }
}

答案 2 :(得分:0)

你可以做几件事:

使用简单的List并使用Linq通过CustomID检索对象:

var elements = myContainer.Where(e=>e.CustomID == new CustomID(...)).ToList();

或者,扩展通用Dictionary类以提供一个Add重载,它知道如何从给定值中设置键:

public class AutoDictionary<K,V> : Dictionary<K,V>
{
   public Func<V,K> KeyGenerator { get; set; }
   public void Add(V value)
   {
      Add(KeyGenerator(V),V);
   }
}

...

var myContainer = new AutoDictionary<CustomId, Element>();
myContainer.KeyGenerator = e=> e.id;
myContainer.Add(myElement);
var elementFromDictionary = myContainer[myElement.id]; //will be the same instance as myElement