Advantages and Limitations of Generics

By allowing you to specify types that are acted on by a generic class or method, the generics feature shifts the burden of type safety from you to the compiler. There is no need to write code to test for the correct data type because it is enforced at compile time. The need for type casting and the possibility of run-time errors are reduced.

Generics provide type safety without the overhead of multiple implementations. For example, you can create a linked list of strings with the following variable declaration:

Dim llist As New LinkedList(Of String)
LinkedList<string> llist = new LinkedList<string>();
LinkedList<String^>^ llist = gcnew LinkedList<String^>();

There is no need to inherit from a base type and override members. The linked list is ready for immediate use. See System.Collections.Generic and System.Collections.ObjectModel for the generic collection types provided by the .NET Framework.

In addition to type safety, generic collection types generally perform better for storing and manipulating value types because there is no need to box the value types.

Generic delegates enable type-safe callbacks without the need to create multiple delegate classes. For example, the Predicate<T> generic delegate allows you to create a method that implements your own search criteria for a particular type and to use your method with methods of the Array type such as Find<T>, FindLast<T>, and FindAll<T>.

Generic delegates can also be used in dynamically generated code without requiring the generation of a delegate type. This increases the number of scenarios in which you can use lightweight dynamic methods instead of generating entire assemblies. For more information, see How to: Define and Execute Dynamic Methods and DynamicMethod.

In many cases, the Visual Basic, Visual C++, and C# compilers can determine from context the types that are used by a generic method call, which greatly simplifies the syntax for using generic methods. For example, the following code shows the short and long forms for calling the BinarySearch generic method to search an array of strings. In the short form, the compilers infer the correct type parameter from the types of the method arguments.

Dim index As Integer = Array.BinarySearch(myArray, "test string")
Dim index As Integer = _
    Array.BinarySearch(Of String)(myArray, "test string")
int index = Array.BinarySearch(myArray, "test string");
int index = Array.BinarySearch<string>(myArray, "test string");
int index = Array::BinarySearch(myArray, "test string");
int index = Array::BinarySearch<String^>(myArray, "test string");

Limitations of Generics

The following are some limitations of generics in the .NET Framework version 2.0:

  • Generic types can be derived from most base classes, such as MarshalByRefObject (and constraints can be used to require that generic type parameters derive from base classes like MarshalByRefObject). However, this release of the .NET Framework does not support context-bound generic types. A generic type can be derived from ContextBoundObject, but trying to create an instance of that type causes a TypeLoadException.

  • Enumerations cannot have generic type parameters. An enumeration can be generic only incidentally (for example, because it is nested in a generic type that is defined using Visual Basic, C#, or C+). For more information, see Enumerations in the Common Type System.

  • Lightweight dynamic methods cannot be generic. For more information about dynamic methods, see Reflection Emit Dynamic Method Scenarios.

  • In Visual Basic, C#, and C++, a nested type that is enclosed in a generic type cannot be instantiated unless types have been assigned to the type parameters of all enclosing types. Another way of saying this is that in reflection, a nested type that is defined using these languages includes the type parameters of all its enclosing types. This allows the type parameters of enclosing types to be used in the member definitions of a nested type. For more information, see "Nested Types" in MakeGenericType.

    Note

    A nested type that is defined by emitting code in a dynamic assembly or by using the MSIL Assembler (Ilasm.exe) is not required to include the type parameters of its enclosing types; however, if it does not include them, the type parameters are not in scope in the nested class.

    For more information, see "Nested Types" in MakeGenericType.

See Also

Concepts

Overview of Generics in the .NET Framework

Generic Collections in the .NET Framework

Generic Delegates for Manipulating Arrays and Lists

Generic Interfaces

Reference

System.Collections.Generic

System.Collections.ObjectModel

Other Resources

Generics in the .NET Framework