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" });