Dictionary.Last()的返回值是否未定义?

时间:2016-09-28 08:01:53

标签: c# dictionary

今天我在一些我正在阅读的代码中遇到了Dictionary.Last()。对我来说,这没有任何意义,因为一本字典没有明确的“最后”概念。元件。检查MSDN向我提供了以下信息:

  

出于枚举的目的,字典中的每个项都被视为表示值及其键的KeyValuePair结构。返回项目的顺序未定义。

这听起来像Last()的结果也是未定义的,但该方法实际上并没有按顺序返回项目,暗示它返回基于项目的项目内部订单。我可能会过度思考这个问题,但那里存在差异。

使用以下代码进行自己的测试导致" Fifteen"每次测试运行时都会一直返回。

class Program
{
    static void Main(string[] args)
    {
        Dictionary<int, string> dictionary = new Dictionary<int, string>();
        dictionary.Add(10, "Ten");
        dictionary.Add(5, "Five");
        dictionary.Add(20, "Twenty");           
        dictionary.Add(2, "Two");
        dictionary.Add(15, "Fifteen");

        Console.WriteLine(dictionary.Last());
        Console.ReadKey();
    }
}

所以现在我想知道是否可以安全地假设Dictionary.Last()返回最后添加的值,或者如果不应该使用该方法,因为文档说明返回项目的顺序< / em>未定义,但未明确说明Last()的行为?

3 个答案:

答案 0 :(得分:4)

SharedPreferences preferences= PreferenceManager.getDefaultSharedPreferences(this); if (!preferences.getBoolean("Man",false)) { // wait 1 second DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.openDrawer(Gravity.LEFT); // wait 1 second DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.openDrawer(Gravity.RIGHT); SharedPreferences.Editor editor=preferences.edit(); editor.putBoolean("Man",true); editor.commit(); } 总是返回最后添加的项目的假设很容易显示为失败,如下所示:

Dictionary.Last()

因此var dict = new Dictionary<Guid, Guid>(); Guid a = Guid.Empty, b = a, c = a, d = a; for (int i = 0; i < 1000; ++i) { var guid = Guid.NewGuid(); dict.Add(guid, guid); if (dict.Last().Key != guid) Console.WriteLine("Failed at iteration " + i); if (d != Guid.Empty) dict.Remove(d); d = c; c = b; b = a; a = guid; } Enumerable.Last()一起使用的返回值未定义。

(对于Dictionary的当前实现,看起来只要删除项目,Dictionary就不再返回最近添加的项目。)

答案 1 :(得分:1)

“我想知道是否可以安全地假设Dictionary.Last()返回最后添加的值”

没有

  

退回商品的顺序未定义

它们可能符合您现在 的顺序,但随着内部实施的变化,未定义的行为可能随时发生变化。

答案 2 :(得分:0)

订单本身由Dictionary的内部定义。因此,它似乎是来自当前实现的 deterministic 并返回相同输入的相同顺序 - 在您的情况下Fifteen将始终是最后一项。然而,由于实际的顺序依赖于内部实现(可能在键的哈希码上),所以不应该依赖于这个顺序,因为它不太可能是你期望的。

特别是订单是一个实现细节。如果依赖于此,当Microsoft希望更改内部代码(而不是API)时,您会遇到问题。