Вот как вы можете это сделать:
public static class Extensions
{
public static IEnumerable<T> MyDistinct<T, V>(this IEnumerable<T> query,
Func<T, V> f,
Func<IGrouping<V,T>,T> h=null)
{
if (h==null) h=(x => x.First());
return query.GroupBy(f).Select(h);
}
}
Этот метод позволяет использовать его, указав один параметр, например .MyDistinct(d => d.Name)
, но он также позволяет указать условие наличия в качестве второго параметра, например:
var myQuery = (from x in _myObject select x).MyDistinct(d => d.Name,
x => x.FirstOrDefault(y=>y.Name.Contains("1") || y.Name.Contains("2"))
);
N.B. Это также позволит вам указать другие функции, такие как, например, .LastOrDefault(...)
.
Если вы хотите выставить только условие, вы можете сделать его еще проще, реализовав его как:
public static IEnumerable<T> MyDistinct2<T, V>(this IEnumerable<T> query,
Func<T, V> f,
Func<T,bool> h=null
)
{
if (h == null) h = (y => true);
return query.GroupBy(f).Select(x=>x.FirstOrDefault(h));
}
В этом случае запрос будет выглядеть так:
var myQuery2 = (from x in _myObject select x).MyDistinct2(d => d.Name,
y => y.Name.Contains("1") || y.Name.Contains("2")
);
N.B. Здесь выражение проще, но заметьте, .MyDistinct2
неявно использует .FirstOrDefault(...)
.
Примечание: В приведенных выше примерах используется следующий демонстрационный класс
class MyObject
{
public string Name;
public string Code;
}
private MyObject[] _myObject = {
new MyObject() { Name = "Test1", Code = "T"},
new MyObject() { Name = "Test2", Code = "Q"},
new MyObject() { Name = "Test2", Code = "T"},
new MyObject() { Name = "Test5", Code = "Q"}
};