题
我有一本字典,比如
Dictionary<Foo,String> fooDict
我逐步浏览字典中的所有内容,例如
foreach (Foo foo in fooDict.Keys)
MessageBox.show(fooDict[foo]);
按照foos添加到字典中的顺序执行此操作,因此添加的第一个项目是返回的第一个foo。
如何更改基数,例如,添加的第三个foo将是返回的第二个foo?换句话说,我想改变它的“索引”。
解决方案
如果您阅读MSDN上的文档,您会看到:
&quot;返回项目的顺序是未定义的。“
您无法保证订单,因为词典不是列表或数组。它意味着通过键查找值,任何迭代值的能力只是一种方便,但顺序不是你应该依赖的行为。
其他提示
您可能对 感兴趣 <中提供的OrderedDicationary
类code> System.Collections.Specialized 命名空间。
如果你看一下最底层的评论,MSFT的某个人发布了这个有趣的说明:
这种类型实际上是错误的;它不是一个“有序”字典,而是一个“索引”字典。虽然,今天没有这种类型的等效通用版本,如果我们将来添加一个,我们可能会命名为'IndexedDictionary'类型。
我认为从这个类派生并制作OrderedDictionary的通用版本是微不足道的。
我没有在域中完全接受教育以正确回答问题,但我有感觉,字典根据键对值进行排序,以便执行快速键搜索。这表明字典根据键比较按键值排序。但是,考虑到对象方法,我认为他们使用哈希码来比较不同的对象,因为不需要用于键的类型。这只是猜测。更有知识的人应该填写更多细节。
为什么你对操纵“索引”感兴趣?字典的目的是用任意类型索引?
我不知道是否有人会发现这有用,但这就是我最终弄清楚的。它似乎工作(我的意思是它不会抛出任何异常),但我仍然有一种方法可以测试它是否正常工作。不过我以前做过类似的事情。
public void sortSections()
{
//OMG THIS IS UGLY!!!
KeyValuePair<ListViewItem, TextSection>[] sortable = textSecs.ToArray();
IOrderedEnumerable<KeyValuePair<ListViewItem, TextSection>> sorted = sortable.OrderBy(kvp => kvp.Value.cardinality);
foreach (KeyValuePair<ListViewItem, TextSection> kvp in sorted)
{
TextSection sec = kvp.Value;
ListViewItem key = kvp.Key;
textSecs.Remove(key);
textSecs.Add(key, sec);
}
}
简短的回答是,自“词典”“代表键和值的集合”以来,应该没有办法。这并不意味着任何排序。你可能发现的任何黑客都不在课堂定义范围内,可能会发生变化。
你可能应该首先问自己,在这种情况下是否真的需要一个词典,或者你是否可以使用KeyValuePairs列表。
否则,这样的事情可能会有用:
public class IndexableDictionary<T1, T2> : Dictionary<T1, T2>
{
private SortedDictionary<int, T1> _sortedKeys;
public IndexableDictionary()
{
_sortedKeys = new SortedDictionary<int, T1>();
}
public new void Add(T1 key, T2 value)
{
_sortedKeys.Add(_sortedKeys.Count + 1, key);
base.Add(key, value);
}
private IEnumerable<KeyValuePair<T1, T2>> Enumerable()
{
foreach (T1 key in _sortedKeys.Values)
{
yield return new KeyValuePair<T1, T2>(key, this[key]);
}
}
public new IEnumerator<KeyValuePair<T1, T2>> GetEnumerator()
{
return Enumerable().GetEnumerator();
}
public KeyValuePair<T1, T2> this[int index]
{
get
{
return new KeyValuePair<T1, T2> (_sortedKeys[index], base[_sortedKeys[index]]);
}
set
{
_sortedKeys[index] = value.Key;
base[value.Key] = value.Value;
}
}
}
客户端代码看起来像这样:
static void Main(string[] args)
{
IndexableDictionary<string, string> fooDict = new IndexableDictionary<string, string>();
fooDict.Add("One", "One");
fooDict.Add("Two", "Two");
fooDict.Add("Three", "Three");
// Print One, Two, Three
foreach (KeyValuePair<string, string> kvp in fooDict)
Console.WriteLine(kvp.Value);
KeyValuePair<string, string> temp = fooDict[1];
fooDict[1] = fooDict[2];
fooDict[2] = temp;
// Print Two, One, Three
foreach (KeyValuePair<string, string> kvp in fooDict)
Console.WriteLine(kvp.Value);
Console.ReadLine();
}
更新:出于某种原因,它不会让我评论我自己的答案。
无论如何,IndexableDictionary与
中的OrderedDictionary不同- &quot; OrderedDictionary的元素不以任何方式排序。所以foreach不会注意数字指数
- 它是强类型的,所以你不必乱用于从DictionaryEntry结构中输出东西 醇>