• 静态属性赋值

先来看 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 //方法结束
}

玩转动态编译 - 高级篇:二,IL设置静态属性,字段和类型转换

  • 小贴士:

每个操作系统都会从堆栈中获取指定数量的参数,比如上一篇中的静态字段/属性取值操作,这个操作不需要用到任何参数,比如执行一个方法,这个方法签名有几个参数,就需要提供几个参数,再比如执行一次比较,需要提供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);
}
测试方法

相关文章:

  • 2022-02-13
  • 2022-01-14
  • 2021-11-20
  • 2022-12-23
  • 2021-10-02
  • 2021-12-12
  • 2022-12-23
  • 2021-10-24
猜你喜欢
  • 2021-10-13
  • 2021-11-11
  • 2022-12-23
  • 2021-12-30
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案