Who's on Dictionary<>.First()?
当您在
键集是确定哪个项是第一个项,还是只是未定义?
好吧,我相信这组键将决定哪个项目是第一个,但不是以一种定义明确(或易于预测)的方式。换句话说,不要假定它总是以相同的方式工作——它和依赖于运行之间保持相同的哈希代码实现一样不安全。
编辑:我相信事实上,插入的顺序确实很重要,与我以前的想法相反。但是,这是特定于实现的(因此在下一个版本中很容易更改)。我相信,在当前的实现中,如果没有删除第一个条目,那么添加的第一个条目将是返回的第一个条目。如果删除了添加的第一个条目,则顺序将被破坏,而不是删除最早的条目。下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using System; using System.Collections.Generic; class Test { static void Main(string[] args) { var dict = new Dictionary<int, int>(); dict.Add(0, 0); dict.Add(1, 1); dict.Add(2, 2); dict.Remove(0); dict.Add(10, 10); foreach (var entry in dict) { Console.WriteLine(entry.Key); } Console.WriteLine("First key:" + dict.First().Key); } } |
结果是10、1、2和"first key:10"-显示最后添加的条目将首先返回。
然而,我想再次强调,框架的各个版本之间的一切都可能发生变化。
我在查看一些代码,这些代码使用foreach循环获取字典对象中的"第一"项。代码假定这是第一个添加到字典中的代码。
最初我认为dictionary.first()方法会更有效。但后来我意识到,在这种情况下,什么项目是第一个的整个概念可能没有多大意义。
Echilon建议,SortedDictionary的开销和功能可能比我需要的要多。我倾向于保存添加的第一个元素的键。
如果你需要字典中的第一个条目,最好使用SortedDictionary。我认为第一个()方法只返回第一个恰好位于顶部的项,但不一定返回第一个添加的项。
未指定实现
但无论如何,还是有理由使用
为什么你不使用
所以你可以写一个这样的函数:
1 2 3 4 | bool ListIsEmpty(IEnumerable<string> list) { return list.FirstOrDefault() == null; } |
像这样使用:
1 2 3 4 5 6 7 8 | if (!ListIsEmpty(dict.Keys)) { Console.WriteLine("Dictionary is not empty"); } if (!ListIsEmpty(dict.Keys.Where(x => x.Contains("foo")) { Console.WriteLine("Dictionary has at least one key containing 'foo'."); } |
并且要知道,为了做出这些决定,代码正在做它必须做的最起码的事情。
编辑:
我应该指出,上面代码所做的另一个假设是:
当在其中一个集合上运行时,它总是为
但是对于一个
我做了更多的挖掘,发现msdn警告说字典中的值和键的顺序是未知的。所以我相信这意味着first()可能不会总是返回与添加更多值相同的值。