Overview of Generics in the .NET Framework
This topic provides an overview of generics in the .NET Framework and a summary of generic types or methods. It also defines the terminology used to discuss generics.
Defining and Using Generics
Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types that they store or use. A generic collection class might use a type parameter as a placeholder for the type of objects that it stores; the type parameters appear as the types of its fields and the parameter types of its methods. A generic method might use its type parameter as the type of its return value or as the type of one of its formal parameters. The following code illustrates a simple generic class definition.
Public Class Generic(Of T)
Public Field As T
End Class
public class Generic<T>
{
public T Field;
}
generic<typename T>
public ref class Generics
{
public:
T Field;
};
When you create an instance of a generic class, you specify the actual types to substitute for the type parameters. This establishes a new generic class, referred to as a constructed generic class, with your chosen types substituted everywhere that the type parameters appear. The result is a type-safe class that is tailored to your choice of types, as the following code illustrates.
Public Shared Sub Main()
Dim g As New Generic(Of String)
g.Field = "A string"
'...
Console.WriteLine("Generic.Field = ""{0}""", g.Field)
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName)
End Sub
public static void Main()
{
Generic<string> g = new Generic<string>();
g.Field = "A string";
//...
Console.WriteLine("Generic.Field = \"{0}\"", g.Field);
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}
static void Main()
{
Generics<String^>^ g = gcnew Generics<String^>();
g->Field = "A string";
//...
Console::WriteLine("Generics.Field = \"{0}\"", g->Field);
Console::WriteLine("Generics.Field.GetType() = {0}", g->Field->GetType()->FullName);
}
Generics Terminology
The following terms are used to discuss generics in the .NET Framework:
A generic type definition is a class, structure, or interface declaration that functions as a template, with placeholders for the types that it can contain or use. For example, the Dictionary<TKey, TValue> class can contain two types: keys and values. Because it is only a template, you cannot create instances of a class, structure, or interface that is a generic type definition.
Generic type parameters, or type parameters, are the placeholders in a generic type or method definition. The Dictionary<TKey, TValue> generic type has two type parameters, TKey and TValue, that represent the types of its keys and values.
A constructed generic type, or constructed type, is the result of specifying types for the generic type parameters of a generic type definition.
A generic type argument is any type that is substituted for a generic type parameter.
The general term generic type includes both constructed types and generic type definitions.
Constraints are limits placed on generic type parameters. For example, you might limit a type parameter to types that implement the IComparer<T> generic interface, to ensure that instances of the type can be ordered. You can also constrain type parameters to types that have a particular base class, that have a default constructor, or that are reference types or value types. Users of the generic type cannot substitute type arguments that do not satisfy the constraints.
A generic method definition is a method with two parameter lists: a list of generic type parameters and a list of formal parameters. Type parameters can appear as the return type or as the types of the formal parameters, as the following code shows.
Function Generic(Of T)(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
T Generic<T>(T arg)
{
T temp = arg;
//...
return temp;
}
generic<typename T>
T Generic(T arg)
{
T temp = arg;
//...
return temp;
}
Generic methods can appear on generic or nongeneric types. It is important to note that a method is not generic just because it belongs to a generic type, or even because it has formal parameters whose types are the generic parameters of the enclosing type. A method is generic only if it has its own list of type parameters. In the following code, only method G is generic.
Class A
Function G(Of T)(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
End Class
Class Generic(Of T)
Function M(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
End Class
class A
{
T G<T>(T arg)
{
T temp = arg;
//...
return temp;
}
}
class Generic<T>
{
T M(T arg)
{
T temp = arg;
//...
return temp;
}
}
ref class A
{
generic<typename T>
T G(T arg)
{
T temp = arg;
//...
return temp;
}
};
generic<typename T>
ref class Generic
{
T M(T arg)
{
T temp = arg;
//...
return temp;
}
};
Visual C++, C#, and Visual Basic all provide full support for defining and consuming generics. For more information, see Generic Types in Visual Basic, Introduction to Generics (C# Programming Guide), and Overview of Generics in Visual C++.
Nested Types and Generics
A type that is nested in a generic type can depend on the type parameters of the enclosing generic type. The common language runtime considers nested types to be generic, even if they do not have generic type parameters of their own. When you create an instance of a nested type, you must specify type arguments for all enclosing generic types.
See Also
Tasks
How to: Define a Generic Type with Reflection Emit
Concepts
When to Use Generic Collections
Overview of Generics in Visual C++
Generic Collections in the .NET Framework
Generic Delegates for Manipulating Arrays and Lists
Advantages and Limitations of Generics
Reference
System.Collections.ObjectModel
Introduction to Generics (C# Programming Guide)