带有通用类型参数的导入方法

时间:2020-01-08 12:58:58

标签: c# cil mono.cecil

我目前正在努力向现有API添加新功能。假设我有一个带有通用类型参数的PerformTediousOperation方法:

void PerformTediousOperation<T>()

此方法在Operator类内部,可以这样调用:

operatorInstance.PerformTediousOperation<T>()

每当用户使用Operator属性标记类型时,我都想创建一个新的Operable实例并调用此方法。

当前,这就是我遇到的问题:

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

发出的IL代码(在C#中)只是PerformTediousOperation();

如何解决此问题,以使发出的代码改为PerformTediousOperation<T>(),其中T将在运行时确定?

请让我知道是否需要更多信息。

1 个答案:

答案 0 :(得分:2)

以下是如何使用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)) }
        };

这将生成PerformTediousOperation<int>()

您可以将任何其他TypeReference实例传递到GenericArguments字段,并且输出将相应地有所不同。例如。如果您改为通过moduleDefinition.ImportReference(typeof(string)),则输出将为PerformTediousOperation<string>()