正如标题所说,我想用Mono.Cecil打电话给那个方法,但我不知道怎么做。
答案 0 :(得分:1)
如何使用Mono.Cecil
注入方法调用:
注入Convert.ToSingle(字符串)调用的代码示例:
目标方法
namespace YourTargetNamespace
{
public class YourTargetClass
{
public Single YourTargetMethod()
{
var str = "1";
return 0; //Convert.ToSingle(str);
}
}
}
在不同的程序集中注入代码和测试
[Test]
public void InjectConverToSingleTest()
{
InjectConverToSingle();
var engine = new YourTargetClass();
Assert.That(engine.YourTargetMethod(), Is.EqualTo(1.0f));
}
public void InjectConverToSingle()
{
const string assemblyName = "YourTargetAssembly.dll";
var assemble = AssemblyDefinition.ReadAssembly(assemblyName);
var type = assemble.MainModule.GetType("YourTargetNamespace.YourTargetClass");
var method = type.Methods.First(m => m.Name == "YourTargetMethod");
var il = method.Body.GetILProcessor();
var requiredPoint = method.Body.Instructions
.First(instruction => instruction.OpCode.Code == Code.Ldstr &&
(string)instruction.Operand == "1");
var convertInstruction = CreateConvertInstruction(assemble.MainModule);
il.InsertAfter(requiredPoint, convertInstruction);
il.InsertAfter(convertInstruction, Instruction.Create(OpCodes.Ret));
assemble.Write(assemblyName);
}
public Instruction CreateConvertInstruction(ModuleDefinition module)
{
var typeConvert = module.Import(typeof(Convert));
var methodToSingle = typeConvert.Resolve()
.Methods.First(method => method.Name == "ToSingle" &&
method.Parameters.Count == 1 &&
method.Parameters[0].ParameterType.FullName == module.TypeSystem.String.FullName);
var importedMethodToSingle = module.Import(methodToSingle);
return Instruction.Create(OpCodes.Call, importedMethodToSingle);
}