Consider removing duplicated elements of List
from a specific class like below:
private List<MyClass> RemoveDuplicatedMyClass(List<MyClass> myObjects)
{
List<MyClass> uniqueMyClasses = new List<MyClass>();
foreach (MyClass item in myObjects)
{
if (uniqueMyClasses.FindAll(itm => itm.myAttribute == item.myAttribute).Count == 0)
{
uniqueMyClasses.Add(item);
}
}
return uniqueMyClasses;
}
I want to refactor RemoveDuplicatedMyClass
to a generic version RemoveDuplicatedItems
like below:
public static List<T> RemoveDuplicatedItems<T>(List<T> items, Predicate<T> match)
{
if (items == null)
{
return new List<T>();
}
List<T> uniqueItems = new List<T>();
foreach (T item in items)
{
// Check if item exists (= already added)! If not add to unique list.
if (uniqueItems.FindAll(match).Count < 1)
{
uniqueItems.Add(item);
}
}
return uniqueItems;
}
Problem: How can I get access to Predicate<T> match
with the inner T item
?
As guys mentioned in comments, it's a good idea to use Enumerable.DistinctBy and one solution is to use dynamic objects:
static List<dynamic> RemoveDuplicatedItems(List<dynamic>? items)
{
if (items == null)
{
return new List<dynamic>();
}
return items.DistinctBy(x=>x.MyAttribute).ToList();
}
and another and I think better option is to use abstraction, if you have some common properties between your classes you can create interface and define type of T as inheritor of that interface:
static List<T> RemoveDuplicatedItems<T>(List<T>? items) where T:ISomeCommonInterface
{
if (items == null)
{
return new List<T>();
}
return items.DistinctBy(x=>x.MyAttribute).ToList();;
}