Recipe13.16.Creating a Generic Type


Recipe 13.16. Creating a Generic Type

Problem

You want to create a generic type using only the reflection APIs.

Solution

You create a generic type similarly to how a nongeneric type is created; however, there is an extra step of creating the type arguments you want to use in creating this generic type and binding these type arguments to the generic type's type parameters at construction. To do this, you will use a new method added to the Type class called BindGenericParameters:

 public static void CreateMultiMap(Assembly asm) {     // Get the type we want to construct.     Type typeToConstruct = asm.GetType(         "CSharpRecipes.DataStructsAndAlgorithms+MultiMap`2");     // Get the type arguments we want to construct our type with.     Type[] typeArguments = new Type[2] {Type.GetType("System.Int32"),                                         Type.GetType("System.String")};     // Bind these type arguments to our generic type.     Type newType = typeToConstruct.MakeGenericType(typeArguments);     // Construct our type.     DataStructsAndAlgorithms.MultiMap<int, string> mm = (         DataStructsAndAlgorithms.MultiMap<int,                 string>)Activator.CreateInstance(newType);     // Test our newly constructed type.     Console.WriteLine("Count == " + mm.Count);     mm.Add(1, "test1");     Console.WriteLine("Count == " + mm.Count); } 

The code to test the CreateMultiMap method is shown here:

 public static void TestCreateMultiMap() {     Assembly asm = Assembly.LoadFrom("C:\\CSharp Recipes 2nd Edition" +              "\\Code\\CSharpRecipes\\bin\\Debug\\CSharpRecipes.exe");     CreateMultiMap(asm); } 

The output of this method is shown here:

 Count == 0 Count == 1 

Discussion

Type parameters are defined on a class and indicate that any type is allowed to be substituted for this type parameter (unless of course there are constraints placed on this type parameter using the where keyword). For example, the following class has two type parameters, T and U:

 public class Foo<T, U> {…} 

Of course you do not have to use T and U; you can instead use another letter or even a full name such as TypeParam1 and TypeParam2.

A type argument is defined as the actual type that will be substituted for the type parameter. In the previously defined class Foo, you can replace type parameter T with the type argument int and type parameter U with the type argument string.

The BindGenericParameters method allows you to substitute type parameters with actual type arguments. This method accepts a single Type array parameter. This Type array consists of each type argument that will be substituted for each type parameter of the generic type. These type arguments must be added to this Type array in the same order as they are defined on the class. For example, the Foo class defines type parameters T and U, in that order. The Type array that you define contains an int type and a string type, in that order. This means that the type parameter T will be substituted for the type argument int and U will be replaced with a string type. The BindGenericParameters method returns a Type object of the type you specified along with the type arguments.

See Also

See the "Type.BindGenericParameters method" topic in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net