Till now we saw an overview on Cecil and two simple examples. Today I want to show how you can handle generics in Cecil.
For the example I’m going to use
// importing the generic type var eq = mainModule.Import(typeof(EqualityComparer<>)); // importing the type of T we want to instantiate the generic type var t = mainModule.Import(typeof(object)); var genericEq = new GenericInstanceType(eq); genericEq.GenericArguments.Add(t); var importedGenericEq = mainModule.Import(genericEq); // getting the method we want to call on the generic instance var defaultMethodDef = importedGenericEq.Resolve(). Methods.Single(m => m.Name == "get_Default"); var methodRef = mainModule.Import(defaultMethodDef); // Important - setting the method declaring type to the correct instantiated type methodRef.DeclaringType = importedGenericEq;
So what we saw here is a regular type importing but with a little additional code, because we need to instantiate the type with the correct
T and last, we must to set the declaring type to the correct instance of the generic type.
This is because there is a difference between the
TypeDef representation of the class – that there is just a one row for our generic class – and the
TypeSpec representation – that has one row for each instantiation. (I’m not going into details of difference between value type and reference type of
T and sharing code implementation.)