BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

.NET Framework
.NET 2.0+

Generic Methods

The .NET framework versions 2.0 and later support the use of generic programming, allowing greater reuse of code with classes and members that can be created without specifying the types that they work with. This article considers generic methods.

Using Generic Methods

Microsoft introduced generics to the C# language with version 2.0 of the .NET framework. In an earlier article, I described the creation of generic types. These are classes and structures that work with data types that are undefined within the type itself and only known when the types are instantiated. If you are new to generics, you should read the article, "Generic Types", before continuing.

Generic methods use a similar syntax to generic types. They allow individual methods to be created that work with types that are defined only when the method is called. A generic method includes one or more type parameters in its signature. Those type parameters can then be used for the return value for the method and in its parameters. This allows the methods to be reused with many different types.

Generic methods share some syntax and functionality with generic classes and structures. However, it is not necessary to create a generic method within a generic type. If you do add a generic method to a generic type, you should not use duplicate type parameter names in a method and its containing class. If you do, the method's type parameter will hide the containing type's and a warning will be generated.

The syntax for a generic method's signature is as follows:

return-type method-name<type-parameters>(parameters)

The most important part of the above syntax is the type-parameters element. Here you specify one or more type parameters in a comma-separated list. If desired, those types can also be used for the return value and some or all of the method's parameters.

The following sample code shows a simple generic method with a single type parameter, named "T". In this case, the BuildList<T> method accepts a number of objects of an undefined type and returns a generic List of the same type. In real-world applications this method serves no purpose. However, it is useful for our demonstration.

List<T> BuildList<T>(params T[] items)
{
    return new List<T>(items);
}

When you call a generic method, you can specify the types to be applied in place of the type parameters by enclosing them between angle brackets (<, >). The following call explicitly states that the method is to be used with strings.

List<string> strings = BuildList<string>("a", "b", "c");

You can also call generic a method without specifying the types that it will use. In the following case, the items passed to the method are all integers. This allows the compiler to infer the type automatically. In some cases type inference is not possible and the type parameters must be provided.

List<int> ints = BuildList(1, 2, 3);

Using Generic Constraints

Type constraints can be applied to individual methods as they are with generic types. Derivation constraints, default constructor constraints and value / reference type constraints are all valid. The syntax is identical to that of generic types with the where keyword being added to the end of the method signature.

In the sample code below, a constraint specifies that T must be a value type. This will prevent the code from compiling because of the existing call that specifies the use of strings, which are reference types.

public List<T> BuildList<T>(params T[] items) where T : struct
{
    return new List<T>(items);
}

Overloading Generic Methods

Generic methods add a new level of method overloading. If two methods use the same standard parameters but define a different number of type parameters, they may co-exist. For example, the following method may be added to the class containing the example generic method. Although the parameter list is identical, the addition of a second type parameter distinguishes the two similar members.

List<T> BuildList<T, K>(params T[] items)
{
    return new List<T>(items);
}
16 May 2010