
he Whidbey release of .NET will include a new Common Language Runtime (CLR) feature called generics. Generics allow you to use a variable to represent a desired data type, and thereby create very generic code (hence the name) that works with any data type.
You define the data type for the generic variable at run time and the CLR substitutes that data type for the variable everywhere in the code that it is used; basically providing you with strongly typed generic code.
Understanding Generics
Generics provide for multiple levels of abstraction, which can make them somewhat difficult to get your head around. So before I show you how to use generics in a more complex "real-world" application, it's best to start with a simple example using structures.
Structures provide a straightforward mechanism for defining a set of related properties and methods. For example, a point consists of an x-value and a y-value, represented by two properties in a point structure.
You could use a structure to define a value with properties for the old value and the new value. If you wanted your value structure to support multiple data types, such as string, integers, and so on, you need to define a different structure for each data type.
In Visual Basic .NET:
' Without generics
Public Structure StringValues
Public sOldValue As String
Public sNewValue As String
End Structure
Public Structure IntValues
Public iOldValue As Int32
Public iNewValue As Int32
End Structure
In C#:
// Without generics
public struct StringValues
{
public string sOldValue;
public string sNewValue;
}
public struct IntValues
{
public int iOldValue;
public int iNewValue;
}
This can be unwieldy, especially if you have many different data types that you need to support.
With generics, you can create one set of code and use a variable to represent the desired type. You define the generic type using the
Of keyword in Visual Basic .NET and the angle bracket (
< >) symbols in C#:
You define the generic type using the Of keyword in Visual Basic .NET and the angle bracket (< >) symbols in C#.
|
|
In Visual Basic .NET "Whidbey":
' With generics
Public Structure Values(Of T)
Public OldValue As T
Public NewValue As T
End Structure
In C# .NET "Whidbey":
// With generics
public struct Values<T>
{
public T OldValue;
public T NewValue;
}
One structure then supports any type of data. You define the desired data type when you create the structure:
In Visual Basic .NET "Whidbey":
Dim a As New Values(Of String)
a.OldValue = ""
a.NewValue = "Generics Test"
Dim b As New Values(Of Int32)
b.OldValue = 0
b.NewValue = 10
In C# .NET "Whidbey":
Values<string> a = new Values<string>();
a.OldValue = "";
a.NewValue = "Generics Test";
Values<int> b = new Values<int>();
b.OldValue = 0;
b.NewValue = 10;
The first three lines in both the Visual Basic .NET and C# examples define a structure of type String and the last three lines define a structure of type Integer. The CLR replaces each reference to the generic variable T with the defined data typeproviding a strongly typed structure.
Strongly typed implies that it enforces the data type at compile time. So if you attempt to set the
OldValue or
NewValue to anything but a String in the first example or an Integer in the second example, you will get a compile error.
Using strong typing improves the quality of your application because it minimizes the possibility of data type errors. And, since it does not have to perform boxing or data type casting, generic code performs better.
Note that in Visual Basic .NET, assigning a value of the wrong type only generates a compile-time error if you use Option Strict On in your project. Otherwise the error occurs at run time.