Jared DC
Jared DC

Reputation: 35

C# How could I pass Anonymous Types to linq group

I have these code. With so many repetitive parts, how should I encapsulate them into a parameter?

            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();
            }

[code duplicated][1] [1]: https://i.sstatic.net/cSSwq.png

Upvotes: 1

Views: 121

Answers (1)

Sweeper
Sweeper

Reputation: 271355

You can extract that query expression into a generic method, like this:

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();

Then, you can replace the duplicated code with:

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);
}

The trick here is that generics can deal with anonymous types just fine.

Upvotes: 1

Related Questions