我有一个类似字典的东西,就像这样:
Dictionary<Foo,String> fooDict
我循环遍历字典中的所有内容,例如:
foreach (Foo foo in fooDict.Keys)
MessageBox.show(fooDict[foo]);
它按照添加到字典中的顺序执行,因此添加的第一项是返回的第一个foo。
我如何更改基数,使例如添加的第三个foo成为第二个返回的foo?换句话说,我想改变它的“索引”。
我有一个类似字典的东西,就像这样:
Dictionary<Foo,String> fooDict
foreach (Foo foo in fooDict.Keys)
MessageBox.show(fooDict[foo]);
您可能会对OrderedDicationary
类感兴趣,它位于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);
}
}
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不同,因为