Reputation: 2891
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
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