【问题标题】:Importing methods with generic type parameters使用泛型类型参数导入方法
【发布时间】:2020-01-08 12:58:58
【问题描述】:

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

void PerformTediousOperation<T>()

这个方法在Operator 类中,可以这样调用:

operatorInstance.PerformTediousOperation<T>()

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

目前,这是我卡住的地方:

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

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

我该如何解决这个问题,以便发出的代码改为PerformTediousOperation<T>(),而T 将在运行时确定?

如果需要更多信息,请告诉我。

【问题讨论】:

标签: c# cil mono.cecil


【解决方案1】:

这是一个如何使用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>()

【讨论】:

  • 什么是runTimeDeterminedType?它不会出现在您的问题或答案的其他地方,这对于其他有相同问题的人来说有点没用
  • 在我的例子中,runTimeDeterminedType 指的是用Operable 属性标记的类型。例如。如果我有一个标记为OperableDummyClass,则生成的IL 代码将为PerformTediousOperation<DummyClass>()
  • 我猜runTimeDeterminedType 是个坏名字;但基本上这个想法是,无论您传递到GenericArguments 字段中的任何TypeReference 都将显示为<> 中指定的类型。
  • 您能否发布一些更独立的代码,对遇到相同问题的其他人有用?
  • @canton7 感谢您的反馈。我已按要求更新了答案。现在清楚了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多