我应该使用一个C#字典,如果我只需要快速查找键,并且值是不相关的?

我需要能够插入条目,然后能够快速确定是否已经插入条目的数据types。 Dictionary似乎适合这种需要(见例)。 但是,我没有使用字典的values 。 我仍然应该使用字典还是有另一个更适合的数据types?

 public class Foo { private Dictionary<string, bool> Entities; ... public void AddEntity(string bar) { if (!Entities.ContainsKey(bar)) { // bool value true here has no use and is just a placeholder Entities.Add(bar, true); } } public string[] GetEntities() { return Entities.Keys.ToArray(); } } 

你可以使用HashSet<T>

HashSet<T>类提供了高性能的集合操作。 一个集合是一个不包含重复元素的集合, 其元素没有特定的顺序

Habib的答案非常好,但对于multithreading环境(如果使用HashSet<T>则必须使用lock来保护对HashSet<T>访问。 我发现自己更倾向于用lock语句创build死锁。 另外, lock每个Amdahl法则会产生更糟的加速,因为添加lock语句会减less实际上并行的代码的百分比。

由于这些原因, ConcurrentDictionary<T,object>符合multithreading环境中的法案。 如果你最终使用一个,然后像你在你的问题中包装它。 只是new object的价值,因为价值将不重要。 您可以validation其源代码中没有lock语句

如果你不需要集合的可变性,那么这将是没有意义的。 但是你的问题意味着你需要它,因为你有一个AddEntity方法。

其他信息2017-05-19 – 实际上, ConcurrentDictionary 内部使用锁,尽pipe本身并不lock语句 – 它使用Monitor.Enter (检查TryAddInternal方法)。 但是,它似乎locking在字典中的单个桶,这意味着将整个事件放在lock语句中的争用将更less。

总而言之, ConcurrentDictionary对于multithreading环境通常更好。

实际上,使用Interlocked方法做一个并发散列集是非常困难的(不可能?)。 我自己试了一下,不断遇到需要同时修改两件事情的问题 – 一般来说只能locking。 我发现的一个解决方法是使用单链表对于散列桶,并且当一个线程需要在节点上操作而不受其他线程干扰时,有意在列表中创build循环; 这会导致其他线程在同一个地方被捕获,直到该线程完成了它的节点并且破坏了这个循环。 当然,它在技术上并没有使用锁,但它并没有很好地扩展。