2010-03-03 57 views
5

我有一个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部分”


我依靠这些项目的顺序是一定的方式。为什么它不如预期,我能做些什么呢?

+0

当然,得到一些书签:) – 2010-03-03 16:19:39

回答

0

不幸的是什么,一个SortedDictionary是速度不够快,我们必须存储的数据量巨大在它里面,一个KeyedCollection失败了手动压缩元素的SequenceNo属性的目的。

严格地说,我们应该重写测序发生的方式,因为我的解决方案是不是最漂亮的:

每一个项目被删除时,新的字典和非删除的项目重新添加到newed词典以保持默认顺序。 - >可怕的做法,我承认。计划在我减轻压力时立即改变它。

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属性设置为只读。

3

你为什么不使用System.Collections.Generic.SortedDictionary,任何理由好像你正在寻找

相关问题