我有Dictionary<Guid, ElementViewModel>
。 (ElementViewModel是我们自己的复杂类型。)
我使用库存标准items.Add(Guid.NewGuid, new ElementViewModel() { /*setters go here*/ });
,
稍后我会删除部分或全部这些项目。
我的ElementViewModel的简单视图是:
class ElementViewModel
{
Guid Id { get; set; }
string Name { get; set; }
int SequenceNo { get; set; }
}
值得注意的是,如果发生移动和复制等其他操作,则在添加后,SequenceNos会在集合中进行压缩。 {1,5,6} - &gt; {1,2,3}
我的删除操作的简单视图是:
public void RemoveElementViewModel(IEnumerable<ElementViewModel> elementsToDelete)
{
foreach (var elementViewModel in elementsToDelete)
items.Remove(elementViewModel.Id);
CompactSequenceNumbers();
}
我将用一个例子说明问题:
我在字典中添加了3个项目:
var newGuid = Guid.NewGuid();
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 1, Name = "Element 1" });
newGuid = Guid.NewGuid();
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 2, Name = "Element 2" });
newGuid = Guid.NewGuid();
items.Add(newGuid, new MineLayoutElementViewModel { Id = newGuid, SequenceNo = 3, Name = "Element 3" });
我删除了2项
RemoveElementViewModel(new List<ElementViewModel> { item2, item3 }); //imagine I had them cached somewhere.
现在我想添加2个其他项目:
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" });
此时对字典的评价,我期望项目的顺序 “元素1”,“元素2,第2部分”,“元素3,第2部分”
但它实际上按以下顺序排列: “元素1”,“元素3,第2部分”,“元素2,第2部分”
我依赖这些项目的顺序是某种方式。为什么它不符合预期,我该怎么办?
答案 0 :(得分:14)
.Net词典在设计上是无序的。
您应该使用KeyedCollection<TKey, TValue>
代替;它将保留项目添加到集合的顺序,并且还将使用哈希表进行快速查找。
例如:
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" });
请注意,如果在将项添加到集合后更改Id
属性,则需要在集合上调用ChangeItemKey
方法。我强烈建议您将Id
属性设置为只读。
答案 1 :(得分:3)
你没有使用System.Collections.Generic.SortedDictionary的任何理由,看起来像你在寻找
答案 2 :(得分:0)
不幸的是,SortedDictionary对于我们必须存储的大量数据来说还不够快,并且KeyedCollection无法手动压缩元素的SequenceNo属性。
严格来说,我们应该重写排序的方式,因为我的解决方案不是最漂亮的:
每次删除某个项目时,都会新建该词典并将未删除的项目重新添加到新建词典中,以保持默认顺序。 - &GT;我承认,这是一种可怕的做法。一旦压力减小,就计划改变它。