September 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Generics in .NET: Type Safety, Performance, and Generality

  • April 21, 2005
  • By Mark Strawmyer
  • Send Email »
  • More Articles »

Defining a Generic Sample Code

To give you a feel for what defining your own types looks like, the following basic example defines a generic type. It really isn't a whole lot different than normal class declarations:

/* * Sample generic type allowing you to add a node and access as * an array. */class TestHolder<T>{   private List<T> childNodes;   public T this[int index]   {      get { return (T)this.childNodes[index]; }   }   public TestHolder()   {      childNodes = new List<T>();   }   public void Add(T node)   {      this.childNodes.Add(node);   }}

The following example code uses the TestHolder defined above. Note that it doesn't use a foreach statement to traverse the list (because it's a custom class and I didn't provide an enumerator):

/* * Code to demonstrate using our TestHolder */TestHolder<TestItem> testCollection = new TestHolder<TestItem>();// Add some numbers to the listfor (int i = 0; i < 200; i++){   testCollection.Add(new TestItem(i));}for (int i = 0; i < 200; i++){   Console.WriteLine("{0}", testCollection[i].ItemValue);}// Wait so you can read the outputSystem.Console.ReadLine();

Quick Performance Comparison

Earlier, I touched on a performance issue due to the boxing and unboxing required with non-generic collections. This section uses the previous examples to perform a quick performance comparison between the two.

Performance Comparison Code

I've incorporated Environment.TickCount into the previous code examples to track the number of milliseconds for execution. It won't be the most scientifically correct comparison ever done, but it should work for this purpose. The results are displayed to the console:

static void Main(string[] args){   TestClassic();   TestGeneric();}static void TestClassic(){   /*    * Code to demonstrate using our TestItemCollection    */   TestItemCollection testCollection = new TestItemCollection();   // Add some numbers to the list   int start = Environment.TickCount;   Console.WriteLine("Starting " + start);   for (int i = 0; i < 200; i++)   {      testCollection.Add(new TestItem(i));   }   System.Collections.IEnumerator listEnumerator =      testCollection.GetEnumerator();   while (listEnumerator.MoveNext())   {      Console.WriteLine("{0}", ((TestItem)                                (listEnumerator.Current)).ItemValue);   }   int end = Environment.TickCount;   int diff = end - start;   Console.WriteLine("Ending time {0}, difference {1}", end, diff);   // Wait so you can read the output   System.Console.ReadLine();}static void TestGeneric(){   /*    * Code to demonstrate using our TestItemCollection    */   List<TestItem> testCollection = new List<TestItem>();   // Add some numbers to the list   int start = Environment.TickCount;   Console.WriteLine("Starting " + start);   for (int i = 0; i < 200; i++)   {      testCollection.Add(new TestItem(i));   }   foreach( TestItem test in testCollection )   {      Console.WriteLine("{0}", test.ItemValue);   }   int end = Environment.TickCount;   int diff = end - start;   Console.WriteLine("Ending time {0}, difference {1}", end, diff);   // Wait so you can read the output   System.Console.ReadLine();}

As the dialogs in Figures 1 and 2 show, the generic version is faster than the non-generic version—even for simply traversing the list. You can imagine the performance savings when you get into larger lists or more complex operations than simply writing to the console.



Click here for a larger image.

Figure 1: Classic Results



Click here for a larger image.

Figure 2: Generic Results

Other Considerations

There is much more to generics than what this article demonstrated. You can apply generics to parameters, method return types, and more. Do some more exploration on your own to get the full understanding.

Future Columns

The next column has yet to be determined. If you have something in particular that you would like to see explained, please e-mail me at mstrawmyer@crowechizek.com.

About the Author

Mark Strawmyer, MCSD, MCSE, MCDBA is a Senior Architect of .NET applications for large and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in architecture, design, and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the second year in a row. You can reach Mark at mstrawmyer@crowechizek.com.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel