c# - DynamicMethod and type checks -
can explain or point explanation why runtime types check not occurs in sample below - string property can set type value ...
stuck in unexpected place , surprised
using system; using system.reflection; using system.reflection.emit; namespace dynamics { internal class program { private static void main(string[] args) { var = new a(); a.name = "name"; console.writeline(a.name.gettype().name); propertyinfo pi = a.gettype().getproperty("name"); dynamicmethod method = new dynamicmethod( "dynamicsetvalue", // name null, // return type new type[] { typeof(object), // 0, objsource typeof(object), // 1, value }, // parameter types typeof(program), // owner true); // skip visibility ilgenerator gen = method.getilgenerator(); gen.emit(opcodes.ldarg_0); gen.emit(opcodes.ldarg_1); gen.emit(opcodes.call, pi.getsetmethod(true)); gen.emit(opcodes.ret); setvalue setmethod = (setvalue)method.createdelegate(typeof(setvalue)); int val = 123; setmethod(a, val); console.writeline(a.name.gettype().name); anothera = new a(); anothera.name = "another a"; setmethod(a, anothera); console.writeline(a.name.gettype().name); } } public class { public string name { get; set; } } public delegate void setvalue(object obj, object val); }
i did little experiment: added method class:
static void setvalue1(a a, object v) { a.name = (string)v; }
doing setvalue1(a, 123);
throws invalidcastexception
of course. disassembled code using ildasm.exe
. setvalue1
looks this:
.method private hidebysig static void setvalue1(class consoleapplication2.a a, object v) cil managed { // code size 15 (0xf) .maxstack 8 il_0000: nop il_0001: ldarg.0 il_0002: ldarg.1 il_0003: castclass [mscorlib]system.string // <--- replace nop il_0008: callvirt instance void consoleapplication2.a::set_name(string) il_000d: nop il_000e: ret } // end of method program::setvalue1
ok, let's replace cast castclass [mscorlib]system.string
nop
, recompile ilasm.exe
.
now call setvalue1 wrong type argument passes , produces same result dynamic method. seem clr not doing type checking in case. documentation says:
during just-in-time (jit) compilation, optional verification process examines metadata , microsoft intermediate language (msil) of method jit-compiled native machine code verify type safe. process skipped if code has permission bypass verification.
in case, running code on local machine, clr trusts il valid.
you can manually verify assembyl running peverify.exe
on output .exe file. return error: program::setvalue1][offset 0x00000004][found ref 'system.object'][expected ref 'system.string'] unexpected type on stack.
there post explores topic: http://www.pcreview.co.uk/forums/net-type-safety-and-net-configuration-tool-t1225543.html
Comments
Post a Comment