- 静态属性赋值
先来看 Reflector反射出的IL源码(感谢Moen的提示),这次用 Release模式编译,去掉那些无用的辅助指令
public void AAA(string s) { MyClass.Name = s; }
.method public hidebysig instance void AAA(string s) cil managed { .maxstack 8 //L_0000: ldarg.1 //这个是真正反射出的内容,但是理论上 这里应该是ldarg.0 //下面一行是我特意修改的,上面的现象我无法解释,请知道的朋友也可以告知一二 L_0000: ldarg.0//参数0,也就是string s这个参数推送的堆栈上 L_0001: stsfld string blqw.IL.Demo.MyClass::Name//使用当前堆栈上最近的一个参数,执行静态字段赋值指令, L_0006: ret //方法结束 }
- 小贴士:
每个操作系统都会从堆栈中获取指定数量的参数,比如上一篇中的静态字段/属性取值操作,这个操作不需要用到任何参数,比如执行一个方法,这个方法签名有几个参数,就需要提供几个参数,再比如执行一次比较,需要提供2个参数等等,每个操作需要的参数都是事先就指定好的
再来看C#中的代码:
public static Action<string> ILTest() { var dm = new DynamicMethod("", null, new[] { typeof(string) }, typeof(MyClass)); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Stsfld, typeof(MyClass).GetField("Name")); il.Emit(OpCodes.Ret); return (Action<string>)dm.CreateDelegate(typeof(Action<string>)); }
进行一些测试
static void Main(string[] args) { var act = ILTest(); MyClass.Name = "111"; Console.WriteLine(MyClass.Name); act("aaaaa"); Console.WriteLine(MyClass.Name); }