C# Как я могу передавать анонимные типы в группу linq

#c# #linq

Вопрос:

У меня есть этот код. С таким количеством повторяющихся частей, как я должен инкапсулировать их в параметр?

             IEnumerable<List<GeminiFileStruct>> delGfl = null;
            if (m_comparemode == GeminiCompareMode.HASH)
            {
                delGfl =
                from i in delGflChecked
                where File.Exists((i.fullPath))
                group i by i.hash into grp
                where grp.Count() > 1
                select grp.ToList();
            }
            else if (m_comparemode == GeminiCompareMode.ExtAndSize)
            {
                delGfl =
                   from i in delGflChecked
                   where File.Exists((i.fullPath))
                   group i by new { i.size, i.extName } into grp
                   where grp.Count() > 1
                   select grp.ToList();
            }
            else
            {
                delGfl =
                   from i in delGflChecked
                   where File.Exists((i.fullPath))
                   group i by i.size into grp
                   where grp.Count() > 1
                   select grp.ToList();
            }
 

[дублированный код][1]
[1]: https://i.stack.imgur.com/cSSwq.png

Ответ №1:

Вы можете извлечь это выражение запроса в общий метод, как показано ниже:

 private IEnumerable<List<GeminiFileStruct>> GroupGeminiFileStructs<T>(IEnumerable<GeminiFileStruct> delGflChecked, Func<GeminiFileStruct, T> keySelector)
    => from i in delGflChecked
       where File.Exists((i.fullPath))
       group i by keySelector(i) into grp
       where grp.Count() > 1
       select grp.ToList();
 

Затем вы можете заменить дублированный код следующим:

 IEnumerable<List<GeminiFileStruct>> delGfl = null;
if (m_comparemode == GeminiCompareMode.HASH)
{
    delGfl = GroupGeminiFileStructs(i => i.hash);
}
else if (m_comparemode == GeminiCompareMode.ExtAndSize)
{
    delGfl = GroupGeminiFileStructs(i => new { i.size, i.extName });
}
else
{
    delGfl = GroupGeminiFileStructs(i => i.size);
}
 

Хитрость здесь в том, что универсальные препараты могут прекрасно справляться с анонимными типами.

Комментарии:

1. Большое спасибо. Это сработало. duplicateGrp = gfl2ienumgrpанонимичный(gfl, i => i.хэш);