There have been some comments recently asking what was the best way to use Generics in C#, so here’s a short blog which sheds some light. Generics were probably the most powerful feature to go into .Net and they allowed developers to define structures, without committing to actual data types. That may sound very complicated but its really not that hard to wrap your head around.
Simple Generic Lists
One of the simplest examples is taken directly from an existing Framework. Within this we have lots of Collections classes for example CompanyCollection, ContactCollection, etc. and these are explicitly created with lots of code for getting a group, array of Company or Contact items from the CompanySearch class.
It's usually seen in this type of context:
// Get a collection of companies
CompanyCollection compCollection = CompanySearch.Browes();
string companyName = compCollection[0].CompName; // display the first company name
Generics give you the same thing out of the box using the List<> function.
// Get a collection of companies using Generics
List<Company> compCollection = CompanySearch.Browes();
string companyName = compCollection[0].CompName;
So what's the advantage? Well for one we don't need the CompanyCollection.cs class file which will save a developer having to write it (cut/paste or use replicator and perhaps introduce bugs). Secondly it's been developed using core functions so it's faster than anything you could write yourself. Also it's guaranteed to give us a stable upgrade path as .Net progresses.
The Syntax
Taking this example a little further, I hear “What’s all this <> crap in the code?”. Well simply, this is the class you are passing into a “generic” (i.e. self defined) method. An easy way to describe this is to think of it as a cut/paste job for the class. Below is an extract of the CompanyCollection class with a Browse method.
using System;
using System.Collections;
namespace BusinessObjects.Companies
{
public class CompanyCollection : CollectionBase
{
public CompanyColelction Browse()
{
CompanyCollection results = new CompanyCollection();
… some code to find a bunch of records and put them in results …
return results;
}
}
If you wanted the same thing for Contacts you would probably cut/paste the code into a new file and replace every occurrence of “"CompanyCollection” with “ContactCollection”. With Generics you would say something like this.
using System;
using System.Collections;
namespace BusinessObjects.Companies
{
public class GenericList<T>
{
public GenericList<T> Browse()
{
GenericList<T> results = new GenericList<T>();
… some code to find a bunch of records and put them in results …
return results;
}
}
Here at compile time the .Net Framework will replace the “T” above with the object value you are passing to the method.
GenericList<Company> myCompanyCollection = new GenericList<Company>(); // replace “T”
myCompanyCollection.Browse();
and
GenericList<Contact> myContactCollection = new GenericList<Contact>(); // replace “T”
myContactCollection.Browse();
Hence in the compiled DLL, you do actually get two classes “generic classes” but you only have to write (or edit, debug, etc.) one!