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