What are “generics”? Well, if you’ve ever used C++, then you’ve probably ran across some code that looked like this:
std::stack myIntStack;
If you have seen this before, then you have a good foundation for understanding generics because the in the statement above is called a “template” which is a very simple version of generics. If you haven’t code like that before, what it is saying is that you would like to create a “stack” data structure that will hold integers. If you used instead, you would have a stack that stores floating point numbers, etc. It’s very handy because you do not have to re-write classes to handle a float one time and then an int the next.
The new version of generics will be a part of C# when Visual Studio .NET 2005 (formerly know as “Whidbey”) ships. In this version, generics are even more powerful than templates in C++. Generics in C# allow you to take a collection class that may normally accept only objects and strongly type that collection class to accept only a specific type of object. There will certainly be times when you WILL NOT want to use generics because you need to store multiple types of objects, but in most cases, you might know ahead of time that this particular collection will consist only of objects of type X. Strong typing isn’t the only benefit though. As Shreyas pointed out to me last week, the compiler can actually optimize your class based on that strong typing to give you a little bit of a performance boost too, which really makes all of this even better. Now that you know the idea behind it, lets look at an example.
In C# 1.0, if you want to build an array of Int32s that is dynamic, you might do:
Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
return (Int32) myStack.Pop();
That’s not too bad, but lets look at the same example with C# 2.0:
Stack<Int32> myStack = new Stack<Int32>();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
return myStack.Pop();
You’ll notice there are not a lot of code changes here, but in the C# 1.0 version, if you push anything other than an Int32 onto that stack, and then try to pop it and cast as an Int32, you better have a try/catch block around it or an “as” statement at the end of it because you’re going to get a runtime error (or crash if you’re unlucky…actually you’ll get an InvalidCastException if you really care). With the 2.0 version, not only is the code faster (the .Push() and .Pop() execute faster) but you don’t have to worry about a runtime exception because the compiler will do the type checking for you (hence the strong typing).
I hope this gives you a little bit better idea about what type of changes are on the way to the best programming language out right now. C# is great as it stands, but generics along with the other new features (which I will blog about soon) are going to make 2.0 even easier to use and faster to execute. And in case you are wondering, IntelliSense will be smart enough to understand the generics as well so the return type of Pop in the example would actually show as Int32 in this case. Nifty stuff indeed.