Overwhelming and Creation of Generics in C#
Introduction
Generics in C# provide a facility for creating high-performance data structures that are specialized by the compiler based on the types that they use. These so-called parameterized types are created so that their internal algorithms remain the same, but also so that the types of their internal data can differ, based on end user preference.
Creation
Generics in C# are declared in much the same way as they are in C++ in order to minimize the learning curve for developers. Programmers can create classes and structures just as they normally have, and by using the angle bracket notation (< and >) they can specify type parameters. When the class is used, each parameter must be replaced by an actual type that the user of the class equipments.
Create a Stack class where a type parameter, called ItemType, is specified and declared in angle brackets after the class declaration. Rather than forcing conversions to and from the base object type, instances of the generic Stack class will accept the type for which they are created and stores data of that type natively. The type parameter, ItemType, acts as a proxy until that type is specified during instantiation and is used as the type for the internal items array-the type for the parameter to the Push method, and the return type for the Pop method:
public class Stack<ItemType> { private ItemType[] items; public void Push(ItemType data) { ... } public ItemType Pop() { ... } }
When a program utilizes the Stack class, as in the following example, you can specify the actual type to be used by the generic class. In this case, you instruct the Stack class to use a primitive integer type by specifying it as a parameter using the angle notation in the instantiation proclamation:
Stack<int> stack = new Stack<int>(); stack.Push(3); int x = stack.Pop();
Your program creates a new instance of the Stack class, for which every ItemType is replaced with the supplied integer parameter. Indeed, when your program creates the new instance of the Stack class with an integer parameter, the native storage of the items array inside the Stack class is now an integer rather than an object. Additionally, your program has eliminated the boxing penalty associated with pushing an integer onto the stack. Furthermore, when your program pops an item off the stack, you no longer need to explicitly cast it to the appropriate type because this particular instance of the Stack class natively stores an integer in its data arrangement.
You have to create a new instance of the Stack class, specifying the new type as the parameter if you want your program to store items other than an integer into a Stack class. Suppose you have a simple Customer type and you wanted your program to use a Stack object to store it. To do so, you simply instantiate the Stack classes with the Customer object as the type parameter and easily reuse your program code:
Stack<Customer> stack = new Stack<Customer>(); stack.Push(new Customer()); Customer c = stack.Pop();
Once your program creates a Stack class with a Customer type as its parameter, it is now limited to storing only Customer types in the stack. Indeed, generics in C# are strongly typed, meaning you can no longer improperly store an integer into the stack, such as in the following example:
Stack<Customer> stack = new Stack<Customer>(); stack.Push(new Customer()); stack.Push(3) // compile-time error Customer c = stack.Pop(); // no cast required.
Have a nice time!