One of the biggest changes of the C# language and the CLR is the introduction of generics. With.NET 1.0, creating a flexible class or method that should use classes that are not known at compile time must be based on the Object class. With the Object class, there’s no type safety during compile time. Casting is necessary. Also, using the Object class for value types has a performance impact.
.NET 2.0 supports generics. With generics the Object class is no longer necessary in such scenarios. Generic classes make use of generic types that are replaced with specific types as needed. This allows for type safety: the compiler complains if a specific type is not supported with the generic class.
Generics are a great feature, especially with collection classes. Most of the .NET 1.0 collection classes are based on the Object type. .NET 2.0 offers new collection classes that are implemented as generics.
Generics are not a completely new construct; similar concepts exist with other languages. For example, C++ templates can be compared to generics. However, there’s a big difference between C++ templates and .NET generics. With C++ templates the source code of the template is required when a template is instantiated with a specific type. Contrary to C++ templates, generics are not only a construct of the C# language; generics are defined with the CLR. This makes it possible to instantiate generics with a specific type in Visual Basic even though the generic class was defined with C#.
See the below Examble.
ArrayList list = new ArrayList();
list.Add(44); // boxing – convert a value type to a reference type
int i1 = (int)list[0]; // unboxing – convert a reference type to a value type
foreach (int i2 in list)
{
Console.WriteLine(i2); // unboxing
}
Boxing and unboxing is easy to use, but it has a big performance impact, especially when iterating through many items.
Instead of using objects, the List<T> class from the namespace System.Collections.Generic allows you to define the type when it is used. In the example here, the generic type of the List<T> class is defined as int, and so the int type is used inside the class that is generated dynamically from the JIT compiler. Boxing and unboxing no longer happens:
List<int> list = new List<int>();
list.Add(44); // no boxing – value types are stored in the List<int>
int i1 = list[0]; // no unboxing, no cast needed
foreach (int i2 in list)
{
Console.WriteLine(i2);
}
Comments are closed.