C# 有没有办法跟踪字典中项目的顺序?
我有一本C# 有没有办法跟踪字典中项目的顺序?,c#,.net,dictionary,hashtable,C#,.net,Dictionary,Hashtable,我有一本字典。(ElementViewModel是我们自己的复杂类型。) 我使用库存标准items.add(Guid.NewGuid,newelementviewmodel(){/*setters go here*/})将项添加到字典中, 在以后的阶段,我会删除部分或全部这些项目 我的ElementViewModel的简化视图如下: class ElementViewModel { Guid Id { get; set; } string Name { get; set; }
字典
。(ElementViewModel是我们自己的复杂类型。)
我使用库存标准items.add(Guid.NewGuid,newelementviewmodel(){/*setters go here*/})将项添加到字典中代码>,
在以后的阶段,我会删除部分或全部这些项目
我的ElementViewModel的简化视图如下:
class ElementViewModel
{
Guid Id { get; set; }
string Name { get; set; }
int SequenceNo { get; set; }
}
值得一提的是,SequenceNos在添加后会在集合中压缩,以防发生移动和复制等其他操作。{1,5,6}->{1,2,3}
我的删除操作的简化视图如下:
public void RemoveElementViewModel(IEnumerable<ElementViewModel> elementsToDelete)
{
foreach (var elementViewModel in elementsToDelete)
items.Remove(elementViewModel.Id);
CompactSequenceNumbers();
}
我删除了2项
RemoveElementViewModel(new List<ElementViewModel> { item2, item3 }); //imagine I had them cached somewhere.
在这一点上对词典进行评估时,我希望条目的顺序是
“要素1”、“要素2,第2部分”、“要素3,第2部分”
但实际上是按照以下顺序:
“要素1”、“要素3第2部分”、“要素2第2部分”
我依赖于这些项目的顺序是某种方式。为什么不像预期的那样,我能做些什么呢?.Net词典的设计是无序的
你应该用一个字母来代替;它将保留项目添加到集合的顺序,并将使用哈希表快速查找
例如:
class ElementViewModelCollection : KeyedCollection<Guid, ElementViewModel> {
protected override Guid GetKeyForItem(ElementViewModel item) { return item.Id; }
}
items.Add(new MineLayoutElementViewModel { Id = Guid.NewGuid(), SequenceNo = 3, Name = "Element 3" });
class ElementViewModelCollection:KeyedCollection{
受保护的覆盖Guid GetKeyForItem(ElementViewModel项){return item.Id;}
}
添加(新的MineLayoutElementViewModel{Id=Guid.NewGuid(),SequenceNo=3,Name=“Element 3”});
请注意,如果在将项添加到集合后更改Id
属性,则需要调用集合上的方法。我强烈建议您将Id
属性设置为只读。您不使用System.Collections.Generic.SortedDictionary的任何原因,似乎都是您要寻找的不幸的是,SortedDictionary不够快,无法存储大量数据,KeyedCollection无法手动压缩元素的SequenceNo属性
严格地说,我们应该重写排序的方式,因为我的解决方案不是最漂亮的:
每次删除项目时,请新建词典,并将未删除的项目重新添加到新建词典中,以保持默认顺序。-->我承认这种做法很可怕。一旦我压力减小,就计划改变它
newGuid = Guid.NewGuid();
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 2, Name = "Element 2, Part 2" });
newGuid = Guid.NewGuid();
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 3, Name = "Element 3, Part 2" });
class ElementViewModelCollection : KeyedCollection<Guid, ElementViewModel> {
protected override Guid GetKeyForItem(ElementViewModel item) { return item.Id; }
}
items.Add(new MineLayoutElementViewModel { Id = Guid.NewGuid(), SequenceNo = 3, Name = "Element 3" });