Reputation: 35
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
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