今天我在一些我正在阅读的代码中遇到了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()
的行为?
答案 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)时,您会遇到问题。