C# Dictionary Удалить объекты с пустым значением
есть метод, который принимает на вход Dictionary<string,object>, object - это вложенный Dictionary<string,string>. Его задача - Если object - Dictionary<string,string> и его значение null, то удалить пару из этого вложенного словаря. Если object - это string, проделать то же самое, но с простым словарем(а не составным). На выходе получаем измененный Dictionary<string,object>. А теперь, собственно, вопрос. Каким образом можно упростить код, заюзав, например LINQ? Мой код:
private object DelNullElements(Dictionary<string,object> Dict)
{
foreach (var item in Dict)
{
if (item.Value is Dictionary<string,string>)
{
foreach(var D in (item.Value as Dictionary<string, string>))
{
if (D.Value == null)
{
(item.Value as Dictionary<string, string>).Remove(D.Key);
}
}
}
else
{
if (item.Value == null)
{
Dict.Remove(item.Key);
}
}
}
return Dict;
}
Ответы (1 шт):
Сделаю обзор кода.
Возвращаемый тип object - почему? Ведь из метода возвращается словарь. И возвращается тот же самый, который поступил на вход.
Я бы изменил сигнатуру метода, сделав тип возврата void. Теперь сразу понятно, что внутри метода не создаётся новый словарь, а изменяется параметр.
Название DelNullElements - не стоит экономить несколько букв. Следует писать слово полностью: Delete. Более того, лично я бы использовать Remove - по аналогии с методом словаря - это будет более последовательно. Далее, мы удаляем значения - values из словаря. В итоге я бы назвал метод RemoveNullValues.
В соответствии с правилами именования, параметр должен быть в camelCasing, то есть dict.
Аналогично переменная D не должна быть заглавной. И лучше дать ей имя не состоящее из одной буквы. Название item уже занято (хорошее название!), поэтому можно назвать её, например, pair - от типа KeyValuePair.
Далее, используем Type pattern ключевого слова is. Это сделает код более лаконичным и уберёт лишние приведения типа (что, кстати, медленно).
Итог:
private void RemoveNullValues(Dictionary<string, object> dict)
{
foreach (var item in dict)
{
if (item.Value is Dictionary<string, string> innerDict)
{
foreach (var pair in innerDict)
{
if (pair.Value == null)
{
innerDict.Remove(pair.Key);
}
}
}
else
{
if (item.Value == null)
{
dict.Remove(item.Key);
}
}
}
}
Теперь о LINQ. Да, переписать код можно. Но я бы не стал. Если использовать метод ToDictionary, то это будет создавать новый словарь. А этот класс - очень тяжеловесная структура данных. И потреблять лишнюю память без причины я не вижу смысла.
А если использовать LINQ просто для прохода по словарю, это практически не сократит код, но опять-таки замедлит его. Вернее, сократит лишь визуально, за счёт устранения фигурных скобок (которые можно убрать и в текущем коде).
Еще можно опционально заменить внутренние if на switch, что опять же суть кода не поменяет.
private void RemoveNullValues(Dictionary<string, object> dict)
{
foreach (var item in dict)
{
switch (item.Value)
{
case Dictionary<string, string> innerDict:
foreach (var pair in innerDict)
{
if (pair.Value is null)
innerDict.Remove(pair.Key);
}
break;
case null:
dict.Remove(item.Key);
break;
}
}
}