2LeggedSpider

Strongly-typed collections

Posted in C# by Sumit Thomas on May 23, 2005

I use DataReader as the data access object in my ASP.NET applications for obvious reasons. To improve the performance of my applications, I also need to utilise the data caching feature in .NET. DataReader cannot be cached, hence I create my custom class with public properties resembling the structure of the table from which the data was fetched, create an instance of this custom class, assign the values from the DataReader to the instance and then add the instance to a Collection object, which can be later cached.

There are many useful Collection classes such as ArrayList, SortedList, Queue, Stack and Hashtable available in System.Collections namespace. These are out-of-the-box classes that you can use for your data manipulation. More information on the .NET collection classes can be found here.

ArrayList is one of the commonly used collection types in .NET and that is attributed to its flexibility in storing data and also its useful methods to manipulate the data. But it also has its own implications. Since ArrayList is implemented internally as an Array of Object type, it is resource intensive as it has to box the data added to it at runtime and also we might receive unexpected exceptions while unboxing the data within the ArrayList. For instance, lets check this code…

ArrayList list = new ArrayList();
list.Add("string value");
list.Add(1);
list.Add(true);

As you can see, we have created an object of type ArrayList and added three items of different data types, namely a string, integer and boolean to it. Now, lets try to retrieve the values from the ArrayList and cast them to string data type, as follows..

for( int i=0; i < list.Count; i++ )
{
	Console.WriteLine( (string)list[i] );
}

Now when we run the above code, we can expect an error when i=1 as we cannot directly cast an integer to string. To avoid this problem we can write our own strongly-typed collection. In a strongly-type collection, we can store data only of a particular type and there won’t be any need to unbox it as we know the type of data residing in the collection. To create a strongly-type collection we can create a custom class that inherits from the CollectionBase abstract class present in the System.Collections namespace. The CollectionBase class implements three interfaces namely IList, IEnumerable and ICollection available in the same System.Collections namespace.

So lets get started. We are going to create a custom collection called Staffs which can hold data of type Staff. Here is the code for Staff.cs

public class Staff
{
	private int staffId;
	private string firstName;
	private string lastName;
	private string department;

	public Staff(int _staffId, string _firstName, string _lastName, string _department)
	{
		staffId = _staffId;
		firstName	 = _firstName;
		lastName	 = _lastName;
		department = _department;
	}

	public int StaffId
	{
		get
		{
			return staffId;
		}
		set
		{
			staffId = value;
		}
	}

	public string FirstName
	{
		get
		{
			return firstName;
		}
		set
		{
			firstName = value;
		}
	}

	public string LastName
	{
		get
		{
			return lastName;
		}
		set
		{
			lastName = value;
		}
	}

	public string Department
	{
		get
		{
			return department;
		}
		set
		{
			department = value;
		}
	}

}//end of class

It is a simple class with four public properties.

Now, we have to create our stongly-type collection which can hold a data of type Staff. Here is the code for Staffs.cs

	public class Staffs : CollectionBase
	{
		public Staffs()
		{
			
		}

		//An indexer of type Staff
		public Staff this[int index]
		{
			get
			{
				return (Staff)List[index];
			}
			set
			{
				List[index] = value;
			}
		}

		//Add object of type Staff to the List
		public int Add( Staff staff )
		{
			return List.Add( staff );
		}
	}

There are many other overridable methods within the CollectionBase class which you can explore.

Lets write a console application to try our strongly-typed collection

		[STAThread]
		static void Main(string[] args)
		{
			Staffs staffs = new Staffs();
			staffs.Add( new Staff(1, "Steven", "Tyler", "Rock" ) );
			staffs.Add( new Staff(2, "Michael", "Jackson", "Pop" ) );
			staffs.Add( new Staff(3, "Marshall", "Mathers", "Rap" ) );
			staffs.Add( new Staff(4, "George", "Bush", "Crap" ) );

			foreach(Staff staff in staffs)
			{
				Console.WriteLine( staff.FirstName + " " + staff.LastName + " is a " + staff.Department + " artist" );
				Console.ReadLine();
			}
		}

If we can ignore the staff data that we entered and focus on collection object ;), we find that it is used similarly to an ArrayList and we don’t have to worry about unboxing the data, as we know it has only objects of type Staff in it.

Eventhough there are several advantages in using strongly-type collection, we have to create a collection for each custom class which might greatly increase the amount of code we have to write. This will however be overcomed with the release of Generics in .NET 2.0

Technorati:
Tagged with: ,