谁在词典。第一个()?

当您在Dictionary集合的实例上调用它时,.NET 3.5扩展方法Enumerable.First()的含义是什么?

这组键是确定哪个项是第一个,还是只是没有定义?

好吧,我相信一组密钥决定哪个项目是第一个,但不是以明确定义(或易于预测)的方式。 换句话说,不要以为它总是以相同的方式工作 – 它依赖于哈希代码实现在运行之间保持相同而不安全。

编辑:我相信事实上,插入的顺序确实很重要,这与我之前的想法相反。 但是,这特定于实现的(因此可以在下一版本中轻松更改)。 我相信,对于当前的实现,添加的第一个条目将是返回的第一个条目( 如果尚未删除)。 如果添加的第一个条目被删除,则排序被破坏 – 并不是最早的条目被删除。 这是一个例子:

 using System; using System.Collections.Generic; class Test { static void Main(string[] args) { var dict = new Dictionary(); 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” – 表示最新添加的条目最终返回。

但是,我想再次强调一切都可以在框架版本之间发生变化。

如果您需要字典中的第一项,则最好使用SortedDictionary。 我认为First()方法只返回恰好位于顶部的第一个项目,但不一定是第一个添加的项目。

我正在查看一些使用foreach循环来获取字典对象中“第一”项的代码。 代码假定这是第一个添加到字典中的代码。

最初我认为Dictionary.First()方法会更有效。 但后来我意识到,在这种背景下,首先是什么项目的概念可能没什么意义。

Echilon建议的SortedDictionary可能比我需要的开销和function更多。 我倾向于只保存添加的第一个元素的键。

未指定实现Dictionary的类中的Keys集合的顺序。 所以你不知道First()将返回什么值。

但无论如何都有理由使用First() – 或者更具体地说,使用FirstOrDefault() 。 如果你有一个采用IEnumerable参数的方法,并且你知道T是一个默认值为null, your method can use的类型null, your method can use FirstOrDefault()来测试对象以查看它是否为空。

为什么要这样做而不是使用Count() ? 利用延迟执行。 如果在生成器上调用FirstOrDefault() ,则生成器会生成一个结果并停止。 如果在生成器上调用Count() ,则生成器必须枚举到列表的末尾。

所以你可以写一个这样的函数:

 bool ListIsEmpty(IEnumerable list) { return list.FirstOrDefault() == null; } 

并像这样使用它:

 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'."); } 

并且知道代码正在做必须做的最低限度才能做出这些决定。

编辑:

我应该指出上面代码的另一个假设是: IEnumerable没有null作为它的第一个项目!

对于字典的Keys集合,或DataRowCollection (我的LINQ的主要用例),或者在其中一个集合上运行时的Where() ,始终保证这一点。

但是不能保证ListList 。 因此,在使用FirstOrDefault()之前,您肯定需要三思而后行。

我做了一些挖掘,发现MSDN警告说字典中的值和键的顺序是未指定的。 所以我认为这意味着First()可能并不总是返回与添加更多值相同的值。