Могут ли Dictionary Keys быть одинаковыми?

206
17 мая 2018, 10:30

Есть Dictionary:

Dictionary < Key, Val> foo;

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

Проблема:

Существуют ситуации, когда объекты-ключи Dictionary уничтожаются. Тогда получается, что Dictionary будет иметь ключи, которые null.

Вопрос:

Как удалить эти ключи и можно ли их удалять обычным способом?

Answer 1

Dictionary<TKey, Tvalue> содержит элементы KeyValuePair(TKey, TValue). Ключи должны быть уникальными. При удалении элемента - удаляется пара целиком, т.е. никаких null-значений в ключах быть не может. Если существует хотя бы одна активная достижимая ссылка на объект - объект не будет удален из памяти.

Отдельный случай, когда объект реализует IDisposable и был вызван метод Dispose(). Но тут есть два важных момента: 1. Использовать такие объекты в качестве ключей не самая хорошая идея; 2. Вызов Dispose(), как правило, выполняет освобождению критичных и/или неуправляемых ресурсов и не влияет на доступность самого объекта. Таким образом может существовать объект на котором применили Dispose(), но он при этом не собран сборщиком мусора, так как на него есть ссылки. Пользы от такого объекта чуть меньше чем ни какой, но он вполне может висеть в словаре в качестве ключа. Таким образом и тут описанной вами проблемы не наблюдается.

Answer 2

Как вариант...

Использоуйте LINQ для определения ключей, value которых = null:

var keys = dictionary.Where(x => x.Value == null).Select(s => s.Key);

Ну и дальше пройтись циклом и удалить из словаря:

foreach (var key in keys)
{
    dictionary.Remove(key);
}

Можно объединить и сделать один LINQ запрос на удаление подобных ключей:

dictionary.Where(x => x.Value == null)
          .Select(s => s.Key).ToList()
          .ForEach(d => dictionary.Remove(d));

Ну а вообще, это желательно делать при удаление value из словаря, а не "когда то, в далекие времена..".

Answer 3

Реализуйте классу объекта-ключа публичный метод Remove().
В этом методе класс будет удалять себя из словаря, в котором он записан, а потом уничтожать свой объект. Когда объект-ключ нужно удалить - вызывайте этот метод.

Решение с поиском null ключей может не помочь, в связи с особенностями реализации сравнения в Unity. Там у них своя обёртка на c# объектом. В итоге, объекта может уже не быть, а обёртка ещё жива и при сравнении с null - будет выдавать false, а при попытке вызвать метод - будет падать ошибка.

READ ALSO
Переадресация при 404 asp mvc

Переадресация при 404 asp mvc

Как сделать, что бы при неверном url происходила переадресация на главную страницу ? Я пытаюсь реализовать это добавлением в webconfig :

209
Убрать рамку с groupbox c#

Убрать рамку с groupbox c#

Надо полностью убрать рамку с groupboxЧтоб остались только элементы внутри

483
C# парсинг html-страницы с помощью AngleSharp

C# парсинг html-страницы с помощью AngleSharp

Подскажите литературу на русском языке по парсингу html с помощью AngleSharp?

206
Не могу добавить в источники данных БД SQLite

Не могу добавить в источники данных БД SQLite

Установил пакеты Nuget для SQLiteВ ссылках он есть

264