29 out of 45 rated this helpful - Rate this topic

Generic Methods (C# Programming Guide)

A generic method is a method that is declared with type parameters, as follows:

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

The following code example shows one way to call the method, using int for the type argument:

public static void TestSwap()
{
    int a = 1;
    int b = 2;

    Swap<int>(ref a, ref b);
    System.Console.WriteLine(a + " " + b);
}

You can also omit the type argument and the compiler will infer it. The following call to Swap is equivalent to the previous call:

Swap(ref a, ref b);

The same rules for type inference apply to static methods as well as instance methods. The compiler is able to infer the type parameters based on the method arguments you pass in; it cannot infer the type parameters solely from a constraint or return value. Therefore type inference does not work with methods that have no parameters. Type inference takes place at compile time before the compiler attempts to resolve any overloaded method signatures. The compiler applies type inference logic to all generic methods that share the same name. In the overload resolution step, the compiler includes only those generic methods on which type inference succeeded.

Within a generic class, non-generic methods can access the class-level type parameters, as follows:

class SampleClass<T>
{
    void Swap(ref T lhs, ref T rhs) { }
}

If you define a generic method that takes the same type parameters as the containing class the compiler will generate warning CS0693 because within the method scope, the argument supplied for the inner T will hide the argument supplied for the outer T. If you require the flexibility of calling a generic class method with type arguments other than the ones provided when the class was instantiated, consider providing another identifier for the method's type parameter, as shown in GenericList2<T> in the following example.

class GenericList<T>
{
    // CS0693
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    //No warning
    void SampleMethod<U>() { }
}

Use constraints to enable more specialized operations on type parameters in methods. This version of Swap<T>, now called SwapIfGreater<T>, can only be used with type arguments that implement IComparable<T>.

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
    T temp;
    if (lhs.CompareTo(rhs) > 0)
    {
        temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}

Generic methods can be overloaded on a number of type parameters. For example, the following methods can all exist in the same class:

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

For more information, see the following sections in the C# Language Specification:

  • 20.6.4 Inference of Type Arguments.

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
First example can be shortened
You can shorten the code to remove the "temp" variable from the first example:
lhs = rhs + lhs; rhs = lhs - rhs; lhs = lhs - rhs;

For example assume lhs = 5 and rhs = 1:
lhs = 1+5
rhs = 6 - 1
rhs now contains 5
lhs = 6 - 5
0lhs now contains 1

Even if rhs < 0 assume lhs = 5 and rhs = -1
lhs = -1+5
rhs = 4 - -1
rhs = 5
lhs = 4 - 5
lhs now contains -1

Edit by SJ at MSFT: And how would this work if T were string, a user-defined class, or some other non-numeric type?
When Creating a New Object in a Generic Method Example
To be complete, when new() is expressed on the method such as:

public List<IFolder> ExtractFolderInformation<T>() where T : IFolder, new()
{

T folder = new T(); // This is the missing example where a T object is new'ed.

List<IFolder> retList = new List<IFolder>();

retLists.Add( folder);

return retList;


}
Advertisement