Av rating:
Total votes: 64
Total comments: 22


Amirthalingam Prasanna
.NET Collection Management
08 December 2005

Using generics to manage a collection of objects

This article focuses on managing a collection of objects using generics, an important addition to the .NET Framework 2.0, and examines the capabilities provided by the generic list.

Introduction

Generics refer to classes and methods that work uniformly on values of different types . They offer some rich capabilities that enhance the coding experience through better performance and easier maintenance. Generics enable you to define classes that use a generic type, and define the type at the time of instantiation or method calls. This makes your code strongly typed, but makes maintenance easier.

Generics enable you to define classes, interfaces, delegates or methods with placeholders for parameterized types used within. At the time of instantiation or method calls, these placeholders are replaced with concrete types.

Let’s say that you need to manipulate a collection of strings. You can use a collection object that is not strongly typed – that is, it manipulates a collection of object instances – or you can create a strongly typed collection to handle a collection of strings.

The first approach will be prone to error because your code will not be restrictive enough nor strongly typed. In the second approach, defining a class that derives from collection for each strongly typed collection you require becomes a maintenance nightmare, since you need to manage many collection classes.

Using generics, a single collection is defined and the type of the objects contained inside is marked with a placeholder. When creating a collection, you specify the type the placeholder denotes.

Generic collections

The .NET Framework 2.0 provides generic collections and interfaces that make it easier to manipulate a collection or define your own. These classes are contained within the namespace System.Collections.Generics.

Below is a simple example that uses a generic List<T> class. Let’s see how we can use it to manipulate a collection of objects, but let’s first define a simple Employee class that we will use inside our list:

C# Code:

public class Employee 
{
  private string name;
private double salary;
public string Name
{

    get { return name; }
set { name = value; }

  }
public double Salary
{
    get { return salary; }
set { salary = value; }
   }
public Employee(string name, double salary)
{

    {
this.name=name;
this.salary=salary;
}
}

Defining and using a collection of employees is simplified when using the List<T>. The <T> denotes the placeholder for the type the list contains. We can define our strongly typed collection by replacing the placeholder with the actual type – "Employee" in our example.

C# Code

System.Collections.Generic.List<Employee> col = new List<Employee>(); 
col.Add(new Employee("John",25500));
col.Add(new Employee("Smith", 32000));
col.Add("This will be a compile error"); //can only add Employees
Employee emp = col [0]; //no typecasting required

Sorting a list

Sorting collections is also simplified using the generic list. The System.Collections.Generic.List has a sort method that accepts a generic Comparison<T>. Comparison<T> is a delegate that takes two parameters of type T, where T is the type (Employee) used to instantiate our collection.

Since we are handling a collection of employees in our sample code, Comparison<Employee> will be a delegate that points to a method that accepts two employee objects. An integer result is returned after the comparison is performed between the two employee objects passed to it.

C# Code

private int CompareBySalary(Employee emp1, Employee emp2) 
{

  return emp1.Salary.CompareTo(emp2.Salary); 
}

The method above compares two employees by salary and returns the comparison result. To sort our generic employee list, we simple plug the sort method into the Comparison<Employee> delegate.

C# Code

Comparison<Employee> compareBySalary; 
compareBySalary = new Comparison< Employee>(CompareBySalary);
col.Sort(compareBySalary);

Searching a list

Searching collections is a matter of using a delegate that does the filtering for us. In our collection example, the Find and FindAll methods in List<T> use a Predicate<T> delegate that accepts a parameter of type T. T is the type used to instantiate our collection that returns a boolean indicating whether or not a match is found.

The following class wraps a method that accepts an employee and indicates in the return whether the salary of the employee is greater than the amount.

C# Code

public class SalaryFilter
{
 
  private int amount;
  public bool FilterBySalary(Employee emp)
  {
     return emp.Salary > amount; 
  }
  public SalaryFilter(int value)
  {
     amount = value; 
  }
}

The above class encapsulates the function of searching by the salary of an employee.

To search our previous list and return all the employees who have a salary greater than 1,000, we need to point to our method defined inside SalaryFilter using a Predicate<Employee> delegate, and pass it to the Find method.

C# Code

Predicate<Employee> filterBySalary; 
SalaryFilter filter = new SalaryFilter(1000);
filterBySalary = new Predicate< Employee>(filter.FilterBySalary);
List<Employee> lstEmps= col.FindAll(filterBySalary);

The difference between the Find and FindAll methods is that Find returns a single object and FindAll returns a collection of objects using a list of the type we are handling.

Iterating a list

Iterating objects and performing simple operations on them in the list has been simplified in .NET 2.0. In .NET 1.1, you would use a ForEach loop to loop through a collection of objects and perform actions. In .NET 2.0, you can use the Action<T> delegate to perform operations on objects inside a list.

Let’s create a class that encapsultes functionality to add the salaries of the employee objects.

C# Code

public class SalaryCalculator
{
   private double amount;
   public double Amount
   {
      get { return amount; }
      set { amount = value; }
   }
   public void CalculateSalary(Employee emp)
   {
     amount += emp.Salary; 
  }
}

We point to the CalculateSalary method using an Action<Employee> delegate, and pass it to the ForEach method of the list.

C# Code

SalaryCalculator calc = new SalaryCalculator(); 
Action<Employee> action;
action = new Action<Employee>(calc.CalculateSalary);
col.ForEach(action);

List conversion

Converting a list is useful when you want a subset of the data in the collection. If you have a collection of employee objects, for example, you might need to retrieve a collection of string objects of the employee names.

In .NET 1.1, you would have to loop through the employee objects, add one to a new collection and return it. In .NET 2.0, you can simply point to a method using a Converter<TInput,TOutput> delegate that accepts a parameter of type TInput (in our case Employee) and it returns an object of type TOutput.

C# Code

private string ConvertEmpToStr(Employee emp) 

  return emp.Name; 

The method above shows how an employee object should be converted to a string object. To convert the entire list, we use the method above with a Converter<Employee,string> delegate.

C# Code

Converter<Employee, string> conv; 
conv = new Converter<Employee, string>(ConvertEmpToStr);
System.Collections.Generic. List<string> empNames =
col.ConvertAll<string>(conv);

Conclusion

This article reviewed the enhancements in .NET 2.0 that enable generic List<T> to better handle collections. Some special features implemented using generics were also introduced.



This article has been viewed 27837 times.
Amirthalingam Prasanna

Author profile: Amirthalingam Prasanna

Prasanna is a software engineer, technical author and trainer with over 7 years experience in the software development industry. He is a Microsoft MVP in the Visual developer category, a MCT and a MCPD on enterprise application development. You can read his blog at www.prasanna.ws and e-mail him at feedback@prasanna.ws

Search for other articles by Amirthalingam Prasanna

Rate this article:   Avg rating: from a total of 64 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: this is good
Posted by: Anonymous (not signed in)
Posted on: Wednesday, July 19, 2006 at 2:25 AM
Message: finally a good overview of
what it is all about with those new collections

Subject: very practical taste of using generics
Posted by: Anonymous (not signed in)
Posted on: Saturday, July 22, 2006 at 1:57 AM
Message: I found the article a very good introduction. It also leaves you asking yourself what other goodies are hidden away in there. I've recommended the article to my team to get them quickly on to the uses of generics.

Excellent for those getting acquainted with .NET 2.0!

Subject: Every thing is clearly explained
Posted by: Anonymous (not signed in)
Posted on: Monday, July 24, 2006 at 6:30 AM
Message:

Thank you for the nice article.Every thing is clearly explained. Really worth reading...


Subject: code snippet not working
Posted by: Anonymous (not signed in)
Posted on: Thursday, July 27, 2006 at 7:55 AM
Message: The article is really excellent and made me easy to understand the use of generics. But the code snippet somehow is giving compilation error :-(

Subject: Prasanna
Posted by: Anonymous (not signed in)
Posted on: Thursday, July 27, 2006 at 3:37 PM
Message: If u can let me know which portion of the code is giving a compilation error would be glad to help u

Subject: code context
Posted by: Anonymous (not signed in)
Posted on: Thursday, August 10, 2006 at 11:04 AM
Message: The context in which the code is useful is missing and therefore reuse.

Subject: Nice Article
Posted by: Anonymous (not signed in)
Posted on: Thursday, August 24, 2006 at 11:03 PM
Message: How would you suggest to encapsulate these methods (Sort, Covert, and Find etc) related to collections?
I think we have to override these methods in our generic collection, isn't it?

Subject: clear and concise
Posted by: Anonymous (not signed in)
Posted on: Wednesday, October 18, 2006 at 1:00 PM
Message: this helped me tremendously! thanks!

Subject: Very good
Posted by: Anonymous (not signed in)
Posted on: Sunday, December 10, 2006 at 11:42 AM
Message: Brief, concise and clear.

Subject: GoodJob
Posted by: Anonymous (not signed in)
Posted on: Sunday, March 11, 2007 at 10:18 PM
Message: Clear , easy to understand! Thank you

Subject: Good Start
Posted by: Anonymous (not signed in)
Posted on: Tuesday, April 10, 2007 at 8:02 AM
Message: Got clear understanding of Generics! Good work

Subject: Thanks!
Posted by: Anonymous (not signed in)
Posted on: Tuesday, May 01, 2007 at 10:47 PM
Message: Thanks a lot! Really appreciated.

Subject: AN error
Posted by: Q.Wang (not signed in)
Posted on: Thursday, June 07, 2007 at 9:31 PM
Message: C# Code

private int CompareBySalary(Employee emp1, Employee emp2) { return emp1.Salary.CompareTo(emp2.Salary); }

the complier show an error message
if change the function to static function
or instantiate this function in another class

the error will disappear.

Subject: Its really good to basic understanding about .NET generics
Posted by: Anonymous (not signed in)
Posted on: Tuesday, July 10, 2007 at 6:44 AM
Message: Its really good to basic understanding about .NET generics

Subject: Its made thru clear explanation
Posted by: Anonymous (not signed in)
Posted on: Monday, August 13, 2007 at 7:30 AM
Message: Very Nice. Simple. Please keep contributing more like these.

Subject: Collection
Posted by: Anonymous (not signed in)
Posted on: Friday, October 12, 2007 at 12:03 AM
Message: It is very good

Subject: Well done
Posted by: Anonymous (not signed in)
Posted on: Friday, December 21, 2007 at 7:59 AM
Message: Thanks for posting this very useful article, and for explaining the topic in a clear and concise manner.

Subject: EXCELLENT
Posted by: Anonymous (not signed in)
Posted on: Wednesday, February 20, 2008 at 12:58 AM
Message: IT IS VERY GOOD

Subject: thx
Posted by: Anonymous (not signed in)
Posted on: Thursday, March 27, 2008 at 4:35 PM
Message: thanks a lot

Subject: Excellent article
Posted by: Anonymous (not signed in)
Posted on: Wednesday, April 23, 2008 at 5:52 AM
Message: Excellent article. Do you have any blog to ask questions.

Subject: Collection matrix to help you decide which collection to use
Posted by: Anonymous (not signed in)
Posted on: Saturday, May 17, 2008 at 9:01 AM
Message: http://www.istcorporate.com/DotNetCollectionChart.htm

Subject: int i = 100;
Posted by: Anonymous (not signed in)
Posted on: Tuesday, August 05, 2008 at 2:44 AM
Message: int i = 100;
double d = 20.5;
ArrayList arrayList = new ArrayList();
arrayList.Add("Joydip");
arrayList.Add(i);
arrayList.Add(d);
for (int index = 0; index <arrayList.Count; index++)
Console.WriteLine(arrayList[index]);

 






recommended site pinvoke

PInvoke.net is a user-driven wiki which provides .NET developers with native method signatures, so they don't have to spend time writing them from scratch.





Damon Armstrong
Customizing the Login Page in SharePoint 2007
 Damon shows how a few simple steps lead you to being able to include the login form in a consistent look and feel to...  Read more...


Silverlight-Speed Loop
 John Bower steps up a gear, produces a Lamborghini, and examines the process of using a high-speed... Read more...

Software Tool Design: Design by Sketching
 Developers can get so used to relying on computers for everything that they can forget how useful it... Read more...

Embedding Help so it will be used
 It is not good enough to make assumptions about the way that users go about getting help when they use... Read more...

Software Tool design: The Three Rs
 To understand the full extent of the requirements of your users when you are redesigning a software... Read more...

Software Tool Design: Remote User Testing
 If you are developing a software product, you'll know that the sooner you can get feedback from the... Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Web Parts in ASP.NET 2.0
 Most Web Parts implementations allow users to create a single portal page where they can personalize... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

Beginning ASP.NET 2.0
 It seems that there is both excitement and confusion surrounding Master Pages and Themes. A big part of... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk