Cómo reemplazar un parámetro de método con una variable utilizando Mono.Cecil.
Estoy creando una utilidad de generación de código para mi aplicación y tengo un problema: no sé cómo puedo reemplazar el parámetro de un método con una variable creada dentro de él.
Ejemplo:
a) Código antes de la generación de código:
public void SomeMethod(Foo foo)
{
DoSomethingWithFoo(foo);
int someInfo = foo.ExamleValue * 12;
// etc
}
b) Código esperado después de la generación de código:
// La clase BitwiseReader se encarga de deserializar una matriz de bytes recibida de un flujo UDP en tipos
public void SomeMethod(BitwiseReader reader)
{
Foo foo = reader.ReadFoo();
DoSomethingWithFoo(foo);
int someInfo = foo.ExamleValue * 12;
// etc
}
He intentado crear un segundo método que convierte BitwiseReader en Foo y lo pasa al método SomeMethod(Foo) real. Pero estoy creando una aplicación de alto rendimiento y ese segundo método aumentó visiblemente el tiempo de procesamiento.
El mayor problema es que Mono.Cecil maneja los parámetros y variables de manera diferente y no sé cómo reemplazar un parámetro por una variable generada.
Preguntas frecuentes para los que dicen “la microoptimización es mala”:
Estoy creando una aplicación de alto rendimiento que maneja decenas de miles de operaciones por segundo. Y como dije, mi solución alternativa con un segundo método disminuyó el rendimiento de manera visible.
davy.ai
Para reemplazar el parámetro de un método con una variable creada dentro del mismo usando Mono.Cecil, deberías seguir estos pasos:
AssemblyDefinition.ReadAssembly
de Mono.Cecil.TypeDefinition.Methods
y la propiedadMethodDefinition.Name
de la definición del tipo.MethodDefinition.Parameters
y el índice del parámetro. Luego, puedes obtener el tipo del parámetro usando la propiedadParameterDefinition.ParameterType
.MethodDefinition.Body.Variables.Add
, pasando el tipo del parámetro original.BitwiseReader
y asignarlo a la nueva variable usando las clasesILProcessor
eInstruction
de Mono.Cecil.Instruction.OpCode
eInstruction.Operand
.Aquí tienes un ejemplo de implementación:
Ten en cuenta que esta implementación asume que ya has importado el método
BitwiseReader.ReadFoo
usando el métodoAssemblyDefinition.MainModule.Import
de Mono.Cecil. También asume que la claseBitwiseReader
se encuentra en la misma biblioteca que el método modificado.