Introduction
.NET 2.0 provides us with a very powerful feature – Generic Lists. It is such a loved feature that we, as programmers, couldn't live any more without it.
With common programming knowledge, we can deal with Generic List as well. However, Generic List comes with some default methods that we can apply to lots of programming situations easily, especially these methods that require a delegate
to define the conditions.
These methods include Exists
, Find
, FindAll
, ForEach
, RemoveAll
, Sort
, and TrueForAll
, etc. If you type your list object in Visual Studio .NET, you will find that the parameter in these methods is Predicate <T>
match. That means you need to use System.Predicate<T> delegate
to define the conditions for the method.
The biggest advantage of these methods is that it saves you a lot of programming time, and makes your code much elegant. Here, I give you the examples to compare these default methods with regular coding practices to show the advantages.
Using the Code
First, let's create an object called Person
that has three properties: Id
, FirstName
and LastName
, a constructor Person(int id, string firstName, string lastName)
, and a method SavePerson()
.
public class Person
{
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
private string lastName;
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public Person()
{
}
public Person(int id, string firstName, string lastName)
{
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public void SavePerson()
{
}
}
Then, in the Page_Load
event (I use web application to show the examples), we add three person
objects into a generic list named person
:
protected void Page_Load(object sender, EventArgs e)
{
List<Person> person = new List<Person>();
person.Add(new Person(1,"John","James"));
person.Add(new Person(2, "Andy", "James"));
person.Add(new Person(3, "Linda", "James"));
}
In the following code, I will list each method with examples.
1. FindAll
FindAll
method with the delegate
returns the found list of the object.
List<Person> newPersonList = person.FindAll(delegate(Person p)
{ return (p.FirstName == "John" || p.FirstName == "Linda"); });
The newPersonList
has two person
s whose first name is John
and Linda
. Here, inside the delegate
should be the object you use for search, inside return should be the search criteria.
If we use regular code, we need to write the following:
List<Person> newPersonList = new List<Person>();
foreach (Person p in person)
{
if (p.FirstName == "John" || p.FirstName == "Linda")
{
newPersonList.Add(p);
}
}
2. Exists
Exists
method with delegate
returns a boolean value. It returns true
if it finds the search results, otherwise, it return false
.
bool exist = person.Exists(delegate(Person p)
{
return (p.FirstName == "John");
}
);
The regular code could be:
bool exist = false;
foreach (Person p in person)
{
if (p.FirstName == "John")
{
exist = true;
break;
}
}
3. TrueForAll
The difference between methods TrueForAll
and Exists
is that Exists
returns true
as long as one instance is found, while TrueForAll
returns true
only if all criteria are met. For example, in some situations, you need to know whether all answers are "Yes" or "No".
bool isAllJFirst = person.TrueForAll(delegate (Person p)
{ return p.FirstName.StartsWith("J"); });
bool isAllJLast = person.TrueForAll(delegate(Person p)
{ return p.LastName.StartsWith("J"); });
isAllJFirst
returns false
because in the person
list, only John
's first name starts with "J". isAllJLast
returns true
because they have a same last name "James
" that starts with "J".
The regular codes could be:
bool exist = false;
foreach (Person p in person)
{
if (p.FirstName == "John")
{
exist = true;
break;
}
}
bool isAllJLast = (countFound == person.Count);
Just like ForEach
loop, this method loops through the whole list to take some actions. For example, we can call SavePerson
method to save each person
's data using the ForEach
method.
person.ForEach(delegate(Person p) { p.SavePerson(); });
The regular code could be:
foreach (Person p in person)
{
p.SavePerson();
}
4. Sort
Method Sort
is a big coding save for list sorting. As we know, if we use regular code to do sort, we probably need to implement Icompare
with many codes. This method really is a one line code deal.
For example, if you want to sort the list by person
id, you can do:
person.Sort(delegate(Person p1, Person p2) { return (p1.Id.CompareTo(p2.Id)); });
By the way, you can also reverse the sorted list by using the method Reverse
:
person.Reverse();
5. RemoveAll
With method RemoveAll
, you can remove the objects that meet your criteria from the list.
The following code removes the person
s whose id is equal to or larger than 2.
person.RemoveAll(delegate(Person p) { return (p.Id >= 2); });
If we use regular coding method, it could be like:
for (int i = person.Count - 1; i >= 0; i--)
{
if (person[i].Id >= 2)
{
person.RemoveAt(i);
}
}
Now, you can see that the Generic list's default methods save our programming time. The shortcoming of these methods might be its readability. A beginner in programming will find that it is not readable compared to the regular coding practices.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.