当“词典”转换为“列表”时,“列表”的顺序是否与“词典”中项目的插入顺序相关。在此示例中,保留了插入顺序,但总是这样吗?或者是字典决定如何存储其项目。
Dictionary<string, int> test = new Dictionary<string, int>
{
{"A",0},
{"Z",1},
{"F",2},
{"J",3}
};
List<KeyValuePair<string, int>> testlist =
new List<KeyValuePair<string,int>>(test);
答案 0 :(得分:4)
NO。它不保留订单。如果它只是偶然和内部实现细节。无法保证元素的枚举顺序应与插入顺序相同。 文档states:
未定义项目的返回顺序。
答案 1 :(得分:3)
确定这一点的唯一方法是查看代码,让我们这样做......
在反编译时,您调用List<T>
的构造函数的实现看起来像
public List(IEnumerable<T> collection)
{
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
ICollection<T> collection1 = collection as ICollection<T>;
if (collection1 != null)
{
int count = collection1.Count;
if (count == 0)
{
this._items = List<T>._emptyArray;
}
else
{
this._items = new T[count];
collection1.CopyTo(this._items, 0);
this._size = count;
}
}
else
{
this._size = 0;
this._items = List<T>._emptyArray;
foreach (T obj in collection)
this.Add(obj);
}
}
正如您所看到的那样,字典会转换为ICollection<T>
,然后调用CopyTo
来引导我们Dictionary<TKey, TValue>
private void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
{
if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
if (index < 0 || index > array.Length)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
if (array.Length - index < this.Count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
int num = this.count;
Dictionary<TKey, TValue>.Entry[] entryArray = this.entries;
for (int index1 = 0; index1 < num; ++index1)
{
if (entryArray[index1].hashCode >= 0)
array[index++] = new KeyValuePair<TKey, TValue>(entryArray[index1].key, entryArray[index1].value);
}
}
通过查看代码,字典的内部项目已编入索引。
根据这些调查结果,如果您要求的是“我的字典的顺序在转换为通用列表时会保留吗?” - 那么它将是(按照.NET) 4.0这是我正在看的版本)。但是,问题是您实际上无法保证将项目的顺序添加到词典中。所以我的建议是转换为使用类似OrderedDictionary<T>
之类的内容或在转换它之前应用OrderBy
子句,例如
var list = new List<KeyValuePair<K, V>>(test.OrderBy(x => x.Value));
答案 2 :(得分:2)
字典不保证商品的顺序。
如果您想维护添加到其中的订单商品,则需要OrderedDictionary。
答案 3 :(得分:0)
标准Dictionary<TKey, TValue>
通常会保留广告订单,但这可能无法保证,您也不应该依赖它。
来自MSDN:
“为了枚举的目的,字典中的每个项目都被视为表示值及其键的KeyValuePair结构。返回项目的顺序是未定义的。”