Finder for any IEnumerable
NHibernate requires you to use IList<T> properties a lot:
public IList<process> Processes { get; set; }
Searching through them is a real pain especially when you live in .NET 2.0 world:
public List<processModel> GetDeleted() { List<process> list= new List<process>(); foreach (Process process in this.Processes) { if (process.IsDeleted) list.Add(process); } return list; }
If you can’t move your project to .NET 3.5 and use extension methods here’s the solution for you.
This is the simple class for making searches on any IEnumerable<T> easier:
public List<processModel> GetDeleted() { return Finder.Create(this.Processes) .FindAll(x => x.IsDeleted); }
Nice, isn’t it?
The Finder class itself:
public class Finder { public static Finder<t> Create<t>(IEnumerable<t> list) { return new Finder<t>(list); } }; public class Finder<t> { private readonly IEnumerable<t> _list; public Finder(IEnumerable<t> list) { _list = list; } public T Find(Predicate<t> func) { foreach (T element in _list) { if (func(element)) return element; } return default(T); } public List<t> FindAll(Predicate<t> func) { List<t> list = new List<t>(); foreach (T element in _list) { if (func(element)) list.Add(element); } return list; } public ReadOnlyCollection<t> FindAllAsReadOnly(Predicate<t> func) { return new ReadOnlyCollection<t>(this.FindAll(func)); } public bool Contains(Predicate<t> func) { foreach (T element in _list) { if (func(element)) return true; } return false; } };
and some tests:
[TestFixture] public class FinderTest { [Test] public void FindAll_ForValueType() { List<int> list = new List<int> { 1, 2, 10, 12 }; Finder<int> finder = Finder.Create(list); Assert.AreEqual(1, finder.FindAll(x => x == 1).Count); } [Test] public void FindAll_ForRefType() { List<box> list = new List<box> { new Box(1), new Box(1), new Box(15) }; Finder<box> finder = Finder.Create(list); Assert.AreEqual(2, finder.FindAll(x => x.Id == 1).Count); } [Test] public void FindAllAsReadOnly_Find_ForRefType() { List<box> list = new List<box> { new Box(1), new Box(1), new Box(15) }; Finder<box> finder = Finder.Create(list); ReadOnlyCollection<box> only = finder.FindAllAsReadOnly(x => x.Id == 1); Assert.AreEqual(2, only.Count); } [Test] public void Find_ForValueType() { List<int> list = new List<int> { 1 ,2, 10, 12 }; Finder<int> finder = Finder.Create(list); Assert.AreEqual(1, finder.Find(x => x == 1)); Assert.AreEqual(12, finder.Find(x => x == 12)); Assert.AreEqual(0, finder.Find(x => x == 999)); } [Test] public void Find_ForRefType() { List<box> list = new List<box> { new Box(21), new Box(2), new Box(15) }; Finder<box> finder = Finder.Create(list); Assert.AreEqual(21, finder.Find(x => x.Id == 21).Id); Assert.AreEqual(2, finder.Find(x => x.Id == 2).Id); Assert.AreEqual(null, finder.Find(x => x.Id == 999)); } [Test] public void Find_ForEmptyList() { Finder<box> finder = Finder.Create(new List<box>()); Assert.IsNull(finder.Find(x => x.Id == 21)); Assert.IsNull(finder.Find(x => x.Id == 2)); Assert.IsNull(finder.Find(x => x.Id == 999)); } internal class Box { readonly int _id; public int Id { get { return _id; } } public Box(int id) { _id = id; } } } ;