У меня есть a 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. элементов вручную.
Строго говоря, мы должны переписать способ, которым происходит упорядочивание, потому что мое решение не самое красивое:
Каждый раз, когда элемент удаляется, обновляйте словарь и повторно добавляйте не удаленные элементы в новый словарь по порядку для поддержания последовательности по умолчанию. -> Я признаю, что это отвратительная практика. Планируйте изменить его, как только на меня будет меньше давления.
.Net Словари неупорядочены по своей природе.
Вместо них следует использовать KeyedCollection
- это сохранит порядок добавления элементов в коллекцию, а также будет использовать хэш-таблицу для быстрого поиска.
Например:
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, похоже на то, что вы ищете