When dealing with collections the common question is how to filter them based on criteria.
The following are a few techniques used to accomplish this. A delegate is like a function pointer.
A predicate is a method that returns true or false.
In the case of List<T> it is possible to pass it a delegate that is a function that returns true or false.
In the examples below I have base object a generic collection of those objects and am using the FindAll method to return only a few of the objects based on matching criteria. There are a number of samples, just un-comment the ones of interest.
23 Persons personList = new Persons(); 24 Person p1 = new Person("Rose", "Bob"); 25 Person p2 = new Person("Rose", "Phil"); 26 Person p3 = new Person("Smith", "Jack"); 27 personList.Add(p1); 28 personList.Add(p2); 29 personList.Add(p3); 30 31 //Sample 1 Using Predicate Technique (long form) 32 //Predicate<Person> filterByLastName; 33 //PersonFilter filter = new PersonFilter("Rose"); 34 //filterByLastName = new Predicate<Person>(filter.FilterByLastName); 35 //List<Person> list = personList.FindAll(filterByLastName); 36 37 //Response.Write("Original Collection Count " + personList.Count.ToString() + "<br />"); 38 //Response.Write("Filtered List Count " + list.Count.ToString() + "<br />"); 39 40 //// this is a shorter version and uses the RemoveAll method to items 41 //personList.RemoveAll(filterByLastName); 42 //Response.Write("After persons removed from the collection Count " + personList.Count.ToString()); 43 44 //Sample 2 shortform version 45 List<Person> list2 = personList.FindAll(new PersonFilter("Rose").FilterByLastName); 46 Response.Write("Count " + list2.Count.ToString()); 47 48 49 //Sample 3 using lambda expression 50 //List<Person> list3 = personList.FindAll( 51 // r => r.LastName == "Rose"); 52 //Response.Write("Count " + list3.Count.ToString()); 53 54 55 //Sample 4 with arrays 56 //Person[] personList2 = { 57 // new Person("Rose", "Bob"), 58 // new Person("Rose", "Phil"), 59 // new Person("Smith", "Jack"), 60 //}; 61 //outputs each person in array 62 //Array.ForEach(personList2, delegate(Person p) 63 //{ 64 // Response.Write(p.LastName + "<br />"); 65 //}); 66 67 //outputs each person after findall 68 //Person[] personList3 = Array.FindAll(personList2, 69 // delegate (Person p) 70 // { 71 // return p.LastName == "Rose"; 72 // } 73 //); 74 //Array.ForEach(personList3, delegate(Person p) 75 //{ 76 // Response.Write(p.LastName + "<br />"); 77 //});
The following are simple classes used in the above exmaples
86 public class Persons : System.Collections.Generic.List<Person> { 87 88 public Persons() { 89 } 90 } 91 92 93 94 public class Person { 95 96 private string _lastName; 97 private string _firstName; 98 public string LastName { 99 get { 100 return _lastName; 101 } 102 set { 103 _lastName = value; 104 } 105 } 106 public string FirstName { 107 get { 108 return _firstName; 109 } 110 set { 111 _firstName = value; 112 } 113 } 114 115 public Person(string lastName, string firstName) { 116 _lastName = lastName; 117 _firstName = firstName; 118 } 119 120 } 121 122 123 public class PersonFilter 124 { 125 126 private string _match; 127 128 public PersonFilter(string match) 129 { 130 _match = match; 131 } 132 133 public bool FilterByLastName(Person per) 134 { 135 if (per.LastName == _match) 136 { 137 return true; 138 } 139 return false; 140 } 141 142 143 public bool FilterByFirstName(Person per) 144 { 145 if (per.FirstName == _match) 146 { 147 return true; 148 } 149 return false; 150 } 151 }
