Импорт методов с параметрами типа generi c - PullRequest
1 голос
/ 08 января 2020

В настоящее время я работаю над добавлением новой функции в существующий API. Допустим, у меня есть метод PerformTediousOperation с параметром типа generi c:

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 Ответ

2 голосов
/ 08 января 2020

Вот пример того, как сгенерировать метод, который имеет типовой параметр c, используя 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>().

...