M.Y. Babt
M.Y. Babt

Reputation: 2891

Importing methods with generic type parameters

I am currently working on adding a new feature to an existing API. Let's say I have a PerformTediousOperation method with a generic type parameter:

void PerformTediousOperation<T>()

This method is inside a Operator class, and can be invoked like this:

operatorInstance.PerformTediousOperation<T>()

I want to create a new Operator instance and invoke this method, whenever the user marks a type with the Operable attribute.

Currently, this is where I am stuck:

MethodReference performTediousOperationMethodReference =
    new MethodReference(
        name: "PerformTediousOperation",
        returnType: moduleDefinition.TypeSystem.Void,
        declaringType: operatorTypeReference)
    {
        HasThis = true
    };

The emitted IL code (in C#) is simply PerformTediousOperation();.

How can I fix this so that the emitted code is instead PerformTediousOperation<T>(), where T will be determined at runtime?

Please let me know if any more information is desired.

Upvotes: 1

Views: 247

Answers (1)

M.Y. Babt
M.Y. Babt

Reputation: 2891

Here is an example of how to generate a method that has a generic type parameter using MonoCecil:

MethodReference performTediousOperationMethodReference =
    new MethodReference(
        name: "PerformTediousOperation",
        returnType: moduleDefinition.TypeSystem.Void,
        declaringType: operatorTypeReference)
    {
        HasThis = true
    };

var genericParameter = new GenericParameter("T", performTediousOperationMethodReference);
performTediousOperationMethodReference.GenericParameters.Add(genericParameter);

GenericInstanceMethod performTediousOperationInstanceMethod = 
    new GenericInstanceMethod(performTediousOperationMethodReference) 
        {
            GenericArguments = { moduleDefinition.ImportReference(typeof(int)) }
        };

This generates PerformTediousOperation<int>().

You may pass any other TypeReference instance to the GenericArguments field, and the output will differ accordingly. E.g. if you pass in moduleDefinition.ImportReference(typeof(string)) instead, the output will be PerformTediousOperation<string>().

Upvotes: 2

Related Questions