在callstack .net上推送和拉取值

时间:2011-11-07 17:55:57

标签: c# .net

我之前已经这样做了,所以我知道可以做到这一点......(虽然记录不完整但是忘了怎么做)。我一直在寻找2个小时,找不到类似的东西。

我想在callstack上推送和拉取值,如下所示:

public void Method1()
{
    InsertMagicClassHere.Push("Key", 1);//or something
    Method2();
}

public void Method2()
{
   int value =  InsertMagicClassHere.Pull("Key");//or something
}

我几乎所有的日志记录方法都需要这个参数..并且不希望用参数传递这3层深层。

2 个答案:

答案 0 :(得分:1)

您正在寻找Reflection.Emit;然而,这不是它的工作原理。

您无法真正发出内联操作码。

相反,您可以发出整个方法/类并将它们作为“临时”程序集加载。然后调用发射的方法。

强制性样本:

public void CreateMethod()
{
    AppDomain currentDomain = AppDomain.CurrentDomain;
    AssemblyBuilder asmbuilder = this.GetAssemblyBuilder("MyAssembly");
    ModuleBuilder mbuilder = this.GetModule(asmbuilder);
    TypeBuilder tbuilder = this.GetTypeBuilder(mbuilder, "MyClass");

    Type[] tparams = { typeof(System.Int32), typeof(System.Int32) };
    MethodBuilder methodSum = this.GetMethod(tbuilder, "Sum", typeof(System.Single), 
                                                                 tparams);

    ILGenerator generator = methodSum.GetILGenerator();

    generator.DeclareLocal(typeof(System.Single));  
    generator.Emit(OpCodes.Ldarg_1);    
    generator.Emit(OpCodes.Ldarg_2);    
    generator.Emit(OpCodes.Add_Ovf);    
    generator.Emit(OpCodes.Conv_R4);    
    generator.Emit(OpCodes.Stloc_0);    

    generator.Emit(OpCodes.Ldloc_0);    
    generator.Emit(OpCodes.Ret);        
}

那你可以做什么

  1. 采用现有方法
  2. 反汇编
  3. 编写代码以在IL级别上发出新方法(使用Reflection.Emit)
  4. 加载发射的组件
  5. 调用您的代码。
  6. 请参阅这些文章以获得良好的开端:

答案 1 :(得分:1)

好。答案是:

CallContext

这有效:

       public void Method1()
    {
        CallContext.SetData("Key", 1);
        Method2();
    }

    public void Method2()
    {
        int value = (int)CallContext.GetData("Key");
    }

就像我说这不是一个众所周知的特征..如果你知道它,你就会知道我指的是什么。

我认为这是一个很酷的功能,它没有多少用途,但仍然是..