Advertisment

Generics in Whidbey

author-image
PCQ Bureau
New Update

Last month, we discussed the new features of  Whidbey, the upcoming .NET Framework version. In this article, we will

understand how the concept of Generics, or template based development for .NET, works. 

Advertisment

Understanding the Why



If you have been a developer who has been involved in template-based development, like ATL and STL, and has recently shifted to .NET based development, you would have probably missed writing generic code. For those who are not clear about the notion of generic code or templates, as they are better known as, the following example will help clear this concept.



Assume you have to write code to implement a Queue data structure that can be used to maintain a queue of integers, floats, longs and other data types as applicable. Consequently, the conventional approach in a non-template based development environment would be to code the Queue implementation for all the required data-types. 

Clearly, this involves a lot of development time, not to mention the code duplicacy that happens. Apart from this, when the final binary is produced, the file size is also bloated.

However, in template-based development, you would write a generic code, which at the time of writing will not specify the particular data type. The data type will be specified during the instantiation of the class, or the invocation of the method. Such classes or methods that use the notion of generic code are termed as template class or template methods in C++.



In Whidbey¸ Microsoft is adding support to write such generic classes and methods. This feature, called Generics, uses various .NET grammars. By the time it is released, the next versions of C# and VB.NET will be supporting Generics. So what does this imply for you, the developer? Well, here it goes:

Advertisment

MSIL will have new opcodes to support generics



You will be able to use the C++ template concepts to write code that will work against various data types

You will not need to fall back on System.Object to implement such kind of generic system.

The FCL (Framework Class Library) will have support for various general-purpose classes, such as List, with their Generic versions.

Advertisment

It means that you could write code, such as below, which specifies what data-type will the Stack implementation use during object instantiation:

GenQueue refGQInt = new GenQueue;

But how do you write code that uses Generics? 



Will Generics work just like C++ templates? Do they give any performance benefits? Let’s answer these questions.

Advertisment

Understanding the How



To exemplify the concept of Generics, we will write an implementation of the Queue data structure. This data structure, thus, will be written once but can be used in the context of various data types, as you shall see. Below is the GenericQueue implementation as a .NET class by the name

GenQueue:

public class GenQueue



{


// private working members


T<> arrData = null;


int iSize; // current working size


int iCurIndex; // current insertion index


int iCurRemovalIndex; // current removal index;


// constructors


public GenQueue()


{


// create a queue of the default size


iSize = 10;


arrData = new T;


iCurIndex = 0;


iCurRemovalIndex = 0;


}


public GenQueue(int iCustomSize)


{


// create a queue of the user specified size


iSize = iCustomSize;


arrData = new T;


iCurIndex = 0;


iCurRemovalIndex = 0;


}


// Add: Inserts an item in the queue


public bool Insert(T tData)


{


if (iCurIndex==iSize)


return false; // the queue is full


// insert item at the queue end...


arrData = tData;


return true;


}


// Remove: Removes an item from the front of the queue


public T Remove()


{


// are there any items in the queue?


if (iCurIndex==iCurRemovalIndex)


throw new Exception(“Queue is empty!”);


T tData = arrData;


iCurRemovalIndex++; // move to the next removal point


return tData;}}





The first noticeable difference can be seen in the class declaration itself:





public class GenQueue



















































This declaration tells the compiler to produce IL that shall take the data type that the consumer of this generic class shall specify. Thus, T is a generic placeholder for any data type that the consumer of the class shall specify when instantiating the class. And here’s how the consumer shall do that:







GenQueue refGQInt = new GenQueue();







As you can see, this instantiation is different from the conventional way of instantiating the class. The angle brackets are used to specify the data type to be used, which is int in the above statement. This implies that for this particular instantiation, the T in 

public class GenQueue

Advertisment

shall be an alias for int. Now that any usage of T shall imply the usage of int, re-read the entire class implementation code and replace all occurrences of T with int. Thus, 

T<> arrData = null;









is actually read as 






int<> arrData = null;





And this is how the .NET JITter sees the code. Subsequent usage to add and/or remove elements to/from the generic queue is rather simple. Here’s how a queue of double elements shall be created:





GenQueue refGQDouble = new GenQueue();


refGQDouble.Insert(1.5);


refGQDouble.Insert(2.6);


refGQDouble.Insert(3.7);


Console.WriteLine(“{0}”, refGQDouble.Remove());


Console.WriteLine(“{0}”, refGQDouble.Remove());


Console.WriteLine(“{0}”, refGQDouble.Remove());










As you can understand for yourself, the code simply creates a generic queue to contain elements of double data-type, adds three elements and then removes them from the queue, while displaying them alongside.

The source code accompanying this article has the complete code that also contains the consumer of the above shown

Gen Queue class. Do refer to it. Of course, it can only be compiled with .NET

Framework Whidbey. 

Kumar Gaurav Khanna



runs wintoolzone.com

Advertisment