Существует ли способ отслеживать упорядочивание объектов в словаре?

У меня есть 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"


Я полагаюсь на порядок этих пунктов, чтобы быть определенным путем. Почему это не как ожидалось и что я могу делать с этим?

5
задан nawfal 31 October 2013 в 07:31
поделиться

3 ответа

К сожалению, SortedDictionary недостаточно быстр для огромного количества данных, которые мы должны хранить в нем, а KeyedCollection лишает смысла уплотнение свойства SequenceNo. элементов вручную.

Строго говоря, мы должны переписать способ, которым происходит упорядочивание, потому что мое решение не самое красивое:

Каждый раз, когда элемент удаляется, обновляйте словарь и повторно добавляйте не удаленные элементы в новый словарь по порядку для поддержания последовательности по умолчанию. -> Я признаю, что это отвратительная практика. Планируйте изменить его, как только на меня будет меньше давления.

0
ответ дан 18 December 2019 в 09:49
поделиться

.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 доступным только для чтения.

14
ответ дан 18 December 2019 в 09:49
поделиться

Любая причина, по которой вы не используете System.Collections.Generic.SortedDictionary, похоже на то, что вы ищете

3
ответ дан 18 December 2019 в 09:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: