You can show them an example of filtering a list of items in several places in your software.
For example, you might have
public List<Person> GetMale(List<Person> people)
{
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (p.IsMale)
results.Add(p);
}
return results;
}
or
public List<Person> GetFemale(List<Person> people)
{
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (!p.IsMale)
results.Add(p);
}
return results;
}
To avoid repeating the foreach
iteration in every method, you will want to extract the actual condition (i.e. a predicate in this case), and have it implemented somewhere else.
So you will replace these two methods with:
public List<Person> Filter(List<Person> people, Func<bool, Person> match)
{
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (match(p))
results.Add(p);
}
return results;
}
and then call it in your code like this:
List<Person> malePersons = Filter(people, p => p.IsMale);
List<Person> femalePersons = Filter(people, p => !p.IsMale);
Note that the actual condition is now extracted outside of the iterating block, and you can reuse the same method to create any custom filtering logic you like. By extracting this logic, you are delegating the problem to someone else, making your code loosely coupled.
Using C# 2.0 anonymous method syntax, calling this method would look like this:
List<Person> malePersons = Filter(people,
delegate (Person p) { return p.IsMale; });
List<Person> femalePersons = Filter(people,
delegate (Person p) { return !p.IsMale; });
or using actual methods:
List<Person> malePersons = Filter(people, MaleMatch);
List<Person> femalePersons = Filter(people, FemaleMatch);
where predicates are defined as:
private bool MaleMatch(Person p)
{
return p.IsMale;
}
private bool FemaleMatch(Person p)
{
return !p.IsMale;
}
It is important to note that we are not passing the result of these methods, but actual method "pointers", so actual results will be returned when the method is called inside the Filter
method.
Note also that LINQ in .Net 3.5 already contains a Where
extension method which does the same thing like this example, and many other methods which use delegates for conditions, projecting and other stuff, so you basically only need to pass a delegate with the appropriate signature.