有没有办法跟踪字典中项目的排序?
我有一个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} - > {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部分”
我依靠这些项目的顺序是一定的方式。为什么它不如预期,我能做些什么呢?
不幸的是什么,一个SortedDictionary是速度不够快,我们必须存储的数据量巨大在它里面,一个KeyedCollection失败了手动压缩元素的SequenceNo属性的目的。
严格地说,我们应该重写测序发生的方式,因为我的解决方案是不是最漂亮的:
每一个项目被删除时,新的字典和非删除的项目重新添加到newed词典以保持默认顺序。 - >可怕的做法,我承认。计划在我减轻压力时立即改变它。
.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
属性设置为只读。
你为什么不使用System.Collections.Generic.SortedDictionary,任何理由好像你正在寻找
当然,得到一些书签:) – 2010-03-03 16:19:39