c# - Mono.Cecil: create local variable and change return statement -


i'm trying rewrite method of property from:

  {     return datastring;  } 

to:

  {     string temp = datastring;     propertylogging.get("datastring", ref temp);     return temp;  } 

so far i've tried differnt things:

//the static method i#m trying insert var getmethod = att.attributetype.resolve().methods.firstordefault(x => x.name == _getmethodname); if (getmethod != null) {     // ilprocessor.insertbefore(returninstruction, ilprocessor.create(opcodes.starg, 1));      ilprocessor.insertbefore(returninstruction, ilprocessor.createloadinstruction(property.name));      // ilprocessor.insertbefore(returninstruction, ilprocessor.create(opcodes.ldloc, 0));     ilprocessor.insertbefore(returninstruction, ilprocessor.create(opcodes.ldloca_s,  0));      ilprocessor.insertbefore(returninstruction, ilprocessor.create(opcodes.call, currentmethod.module.importreference(getmethod)));  } 

but ends in code (decompiled ilspy):

get {     string text = this.datastring;     string arg_17_0 = text;     string text2;     propertylogging.get("datastring", ref text2);     return arg_17_0; } 

the il code have is:

il_0000:  nop          il_0001:  ldarg.0      il_0002:  ldfld       userquery.datastring il_0007:  stloc.0     // text il_0008:  ldloc.0     // text il_0009:  stloc.1     // arg_17_0 il_000a:  ldnull       il_000b:  stloc.2     // text2 il_000c:  ldstr       "datastring" il_0011:  ldloca.s    02 // text2 il_0013:  call        userquery+propertylogging.get il_0018:  nop          il_0019:  ldloc.1     // arg_17_0 il_001a:  stloc.3      il_001b:  br.s        il_001d il_001d:  ldloc.3      il_001e:  ret     

but need is:

il_0000:  nop          il_0001:  ldarg.0      il_0002:  ldfld       userquery.datastring il_0007:  stloc.0     // temp il_0008:  ldstr       "datastring" il_000d:  ldloca.s    00 // temp il_000f:  call        userquery+propertylogging.get il_0014:  nop          il_0015:  ldloc.0     // temp il_0016:  stloc.1      il_0017:  br.s        il_0019 il_0019:  ldloc.1      il_001a:  ret  

i've tried ti create new variable in method body, don't have clue how use it.

does know how correctly rewrite method?

thanks in advance

c# code before:

public string datastring {    { return _datastring; } } 

il code before:

.method public hidebysig specialname  instance string get_datastring () cil managed  { // method begins @ rva 0x2050 // code size 12 (0xc) .maxstack 1 .locals init (     [0] string )      il_0000: nop     il_0001: ldarg.0     il_0002: ldfld string classlibrary1.class1::_datastring     il_0007: stloc.0     il_0008: br.s il_000a     il_000a: ldloc.0     il_000b: ret } // end of method class1::get_datastring 

rewrite:

public void interceptpropertygetter() {     // module property exist     var module = moduledefinition.readmodule(@"c:\temp\classlibrary1.dll");      // property method     typedefinition mytype = module.types.first(type => type.name == "class1");     var property =          mytype.properties.first(prop => prop.name == "datastring").getmethod;      // _datastring field     fielddefinition datastringdef =          mytype.fields.first(field => field.name == "_datastring");     fieldreference datastringref = module.import(datastringdef);      // propertylogging static method     methoddefinition propertyloggingdef =          mytype.methods.first(method => method.name == "propertylogging");     methodreference propertyloggingref = module.import(propertyloggingdef);      // clear method (variables , instructions )     property.body.variables.clear();     property.body.instructions.clear();      // define , init locals     property.body.initlocals = true;     var tempvar = new variabledefinition("temp", module.typesystem.string);     property.body.variables.add(tempvar);      // write il     var processor = property.body.getilprocessor();     processor.emit(opcodes.ldarg_0);     processor.emit(opcodes.ldfld, datastringref);     processor.emit(opcodes.stloc_0);     processor.emit(opcodes.ldstr, "datastring");     processor.emit(opcodes.ldloca_s, tempvar);     processor.emit(opcodes.call, propertyloggingref);     processor.emit(opcodes.ldloca_s, tempvar);     processor.emit(opcodes.ret);     processor.body.optimizemacros();      // save new module     module.write(@"c:\temp\classlibrary1_new.dll"); } 

c# code after:

public string datastring {         {         string datastring = this._datastring;         class1.propertylogging("datastring", ref datastring);         return datastring;     } } 

il code after:

.method public hidebysig specialname  instance string get_datastring () cil managed  {   // method begins @ rva 0x2050   // code size 22 (0x16)   .maxstack 2   .locals init (    [0] string   )     il_0000: ldarg.0     il_0001: ldfld string classlibrary1.class1::_datastring     il_0006: stloc.0     il_0007: ldstr "datastring"     il_000c: ldloca.s 0     il_000e: call void classlibrary1.class1::propertylogging(string, string&)     il_0013: ldloca.s 0     il_0015: ret } // end of method class1::get_datastring 

decompile made ilspy.

this not way (for example don't must clear , can add nop instructions , use unshort version of instructions) think understand how that.