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.

Reflection
.NET 2.0+

Reflecting Generic Method Information

The sixteenth part of the Reflection tutorial continues the examination of reflection when used with generics. This article looks at the processes for extracting information about generic methods, their type parameters and generic method definitions.

Generic Methods

Generic methods are methods that include type parameters. The types that a generic method operates upon or returns are set each time the method is called. This allows you to create more reusable code; rather than creating multiple, similar methods for each type that may be operated upon, a single generic method will often suffice. With the introduction of generics, methods can be broadly categorised into one of several groups:

  • Non-Generic Methods. These are standard methods, similar to those available in the earliest versions of the .NET framework. They do not include type parameters.
  • Generic Methods. These are methods with generic type arguments. The types are provided when the method is called.
  • Closed Constructed Methods. These are generic methods where all of the types of the type arguments have been assigned as real types. These methods can be invoked.
  • Open Constructed Methods. An open generic method includes one or more type parameters that have not yet been assigned actual types. They can also include some assigned type arguments.
  • Generic Method Definition. A generic method definition is a generic method where all of the type arguments are open. These can be used as a template for generating constructed methods via reflection.

You can reflect over a generic method in the same manner as you would a non-generic version, via the MethodInfo class. In additional to the functionality described earlier in the tutorial for reflecting methods, .NET 2.0 adds extra functionality to MethodInfo for dealing with generic methods. This includes properties that allow you to determine which of the above types applies, and methods that allow you to create constructed methods from a method definition or obtain a method definition for a generic method.

The principles described in this article are very similar to those in the previous instalment of the tutorial, "Reflecting Generic Type Information". As such, the descriptions here are shorter than those in the earlier article. If you haven't already, you might consider reading that article first.

For the code samples in this article we'll use the following test class, which contains a single generic method.

public class TestClass
{
    public T1 TestMethod<T1, T2>(T2 testParam)
    {
        return default(T1);
    }
}

As we'll be using types from the System.Reflection namespace, you should include the following using directive in your code:

using System.Reflection;

Determining the Type of a Method

The types of method described above each provide different functionality. For example, standard methods and closed constructed methods can be invoked using reflection but open constructed methods and generic method definitions cannot. Understanding the type of method that you are working with is, therefore, important. We can determine the type by reading the values of three Boolean properties of the MethodInfo class.

The IsGenericMethod property returns true for any method that includes generic type arguments and false for methods that do not. IsGenericMethodDefinition returns true only when all of the type arguments for a generic method are unassigned and false for non-generic methods or generic methods with one of more assigned type parameters. The third Boolean property, ContainsGenericParameters, returns true for generic methods that include one or more unassigned type arguments. By combining the three property values you can categorise the method, as shown in the following table:

Method CategoryIsGenericMethodContainsGenericParametersIsGenericMethodDefinition
Non-Generic Methodfalsefalsefalse
Generic Method Definitiontruetruetrue
Open Constructed Methodtruetruefalse
Closed Constructed Methodtruefalsefalse

The sample code below shows the property values for our test method, which is a generic method definition.

Type type = typeof(TestClass);
MethodInfo method = type.GetMethod("TestMethod");

Console.WriteLine(method.IsGenericMethod);
Console.WriteLine(method.IsGenericMethodDefinition);
Console.WriteLine(method.ContainsGenericParameters);

/* OUTPUT

True
True
True

*/

Retrieving a Generic Method's Type Parameters

Once you have determined that the method you are reflecting over is generic, you can obtain the details of its type arguments using the GetGenericArguments method. This returns an array of System.Type objects in the order in which they appear in the method. In the sample code below, the type arguments are open constructed types which could be further examined using the techniques described in the previous article in this series.

Type type = typeof(TestClass);
MethodInfo method = type.GetMethod("TestMethod");

Console.WriteLine(method.GetGenericArguments().Length);
Console.WriteLine(method.GetGenericArguments()[0]);
Console.WriteLine(method.GetGenericArguments()[1]);

/* OUTPUT

2
T1
T2

*/
30 June 2012