0

我最近发现了生产代码,包括对 .NET 的排序Dictionary<string,CustomObject>。基本上是将字典复制到临时字典,然后 .Clear() 原始字典并插入通过 Linq 表达式排序的 KeyValuePairs,按 CustomObjects 中的 DateTime 值。

我预计此代码不起作用并且已经将其删除,并期望无法对字典(以及 HashSet)进行排序。然后我编写了以下测试代码,令我惊讶的是,当使用 foreach 循环进行迭代时,它显示了字典的排序输出。

这是当前实现中的随机效应Dictionary<TKey, TValue>,它可能在当前情况下有效,但在 .NET 的另一个实现中失败?或者它是在 .NET 词典中使用的标准功能?

我仍然认为生产代码有问题,但可以正常工作。如果订单是在我找到排序例程的地方以外的地方使用的,我应该删除它吗,需要长时间的测试,还是让它保持原样安全?

这是我的测试代码:

static void Main(string[] args)
{
    var rnd = new Random();
    var dict = new Dictionary<int, string>();
    for (int i = 0 ; i < 10 ; i++)
    {
        int rndValue;
        do
        {
            rndValue = rnd.Next(100);
        }
        while (dict.ContainsKey(rndValue));

        dict.Add(rndValue, "MyValue#" + i);
    }

    foreach (KeyValuePair<int, string> pair in dict)
    {
        Console.WriteLine("Key: " + pair.Key + ", Value: " + pair.Value);
    }

    Console.Write("Enter...");
    Console.ReadLine();

    var dictBuff = dict.ToDictionary(p => p.Key, p => p.Value);
    dict.Clear();

    var sortdict = from pair in dictBuff orderby pair.Key ascending select pair;

    foreach (KeyValuePair<int, string> pair in sortdict)
    {
        dict.Add(pair.Key, pair.Value);
    }

    Console.WriteLine("'Sorted' Dictionary:");

    foreach (KeyValuePair<int, string> pair in dict)
    {
        Console.WriteLine("Key: " + pair.Key + ", Value: " + pair.Value);
    }

    Console.Write("Enter...");
    Console.ReadLine();

}
4

2 回答 2

5

它基于当前的实现,但不能保证跨实现。除非您使用SortedDictionary或更改最后一个 foreach 循环以迭代 dict.OrderBy(pair => pair.Key),否则无法保证顺序。

从文档(备注部分)

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

于 2012-10-16T16:46:32.073 回答
1

Dictionary 只是一个带有每个元素的标识符的列表,因此元素将按照它们被放入的顺序返回。但是,不能保证没有人例如删除一个元素只是为了再次插入它,这会使它又在后面。

如果您想确保 Dictionary 保持排序状态,我建议您使用SortedDictionary类。

或者,您可以让 LINQ 在需要时对字典进行排序。

顺便说一句,您可以替换此代码部分:

    var sortdict = from pair in dictBuff orderby pair.Key ascending select pair;

    foreach (KeyValuePair<int, string> pair in sortdict)
    {
        dict.Add(pair.Key, pair.Value);
    }

    foreach (var pair in dictBuff.OrderBy(x => x.Key))
    {
        //dict.Add(pair.Key, pair.Value);
        //meaningful code here
    }

更新

您可以做另一件事而不是使用 SortedDictionary:使用 aList<KeyValuePair<int, string>>或 Array 而不是Dictionary<int, string>. 迭代时的用法完全一样,但您将无法使用索引器list[someItem]。然后,您需要做list.Single(x => x.Key == someItem)或替代使用Firstor FirstOrDefault

//var sortedList = dictBuff.OrderBy(x => x.Key).ToArray();
var sortedList = dictBuff.OrderBy(x => x.Key).ToList();

应该做的伎俩。

于 2012-10-16T16:52:02.237 回答