<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>



      如下所示的是一個(gè).NET程序。我們?cè)谶@段程序中定義了一個(gè)作整數(shù)加法運(yùn)算的Add方法,但是我希望將針對(duì)這個(gè)方法的調(diào)用轉(zhuǎn)移到另一個(gè)Add2方法上,為此我定義了一個(gè)Override方法。
      class Program { static void Main() { Override(() => Add(default, default), ()
      => Add2(default, default)); Console.WriteLine($"Add(1, 1) == {Add(1, 1)}");
      Console.ReadLine(); }public static int Add(int x, int y) => x + y; public static
      int Add2(int x, int y) => x + y + 1; public static void
      Override(Expression<Action> originalCall, Expression<Action> targetCall); }
      從如下所示的輸出可以看出:雖然源程序我們調(diào)用的是Add方法,實(shí)際上最終的調(diào)用被轉(zhuǎn)移到Add2方法上。


      <https://img2018.cnblogs.com/blog/19327/201908/19327-20190814204316432-1731870787.png>

      我們知道通過C#編寫的.NET程序在編譯后會(huì)轉(zhuǎn)化成IL
      Code,在運(yùn)行時(shí)以及時(shí)編譯的方式轉(zhuǎn)化成機(jī)器指令。如果想“篡改”某個(gè)方法的實(shí)現(xiàn),要么在JIT之前改變IL代碼,要么直接修改最終的機(jī)器指令。Override方法采用的是第二種解決方案,如下所示的該方法的實(shí)現(xiàn),基本的思路就是將將原方法的機(jī)器指令修改為JUMP(對(duì)應(yīng)x86二進(jìn)制為
      0xE9)指令實(shí)現(xiàn)向目標(biāo)方法的跳轉(zhuǎn)。
      public static void Override(Expression<Action> originalCall, Expression<Action>
      targetCall) {var originalMethod =
      ((MethodCallExpression)originalCall.Body).Method;var targetMethod =
      ((MethodCallExpression)targetCall.Body).Method;
      RuntimeHelpers.PrepareMethod(originalMethod.MethodHandle);
      RuntimeHelpers.PrepareMethod(targetMethod.MethodHandle);var sourceAddress =
      originalMethod.MethodHandle.GetFunctionPointer();var targetAddress = (long
      )targetMethod.MethodHandle.GetFunctionPointer();int offset = (int
      )(targetAddress - (long)sourceAddress - 4 - 1); byte[] instruction = { 0xE9, //
      JUMP (byte)(offset & 0xFF), (byte)((offset >> 8) & 0xFF), (byte)((offset >> 16)
      &0xFF), (byte)((offset >> 24) & 0xFF) }; Marshal.Copy(instruction, 0,
      sourceAddress, instruction.Length); }
      這個(gè)方式有時(shí)候會(huì)很有用,我最近應(yīng)用的場(chǎng)景是希望篡改.NET
      Core應(yīng)用中針對(duì)IHostEnvironment的如下三個(gè)擴(kuò)展方法的實(shí)現(xiàn),因?yàn)槲覀兊牟渴瓠h(huán)境并沒有按照默認(rèn)的命名約定(Development、Staging和Production)這樣導(dǎo)致了這三個(gè)方法返回錯(cuò)誤的結(jié)果。但是IsDevelopment方法的返回結(jié)果在.NET
      Core服務(wù)承載系統(tǒng)中很重要,所以不得不篡改它的實(shí)現(xiàn)邏輯。
      public static class HostEnvironmentEnvExtensions { public static bool
      IsDevelopment(this IHostEnvironment hostEnvironment) =>
      hostEnvironment.IsEnvironment(Environments.Development); public static bool
      IsProduction(this IHostEnvironment hostEnvironment) =>
      hostEnvironment.IsEnvironment(Environments.Production);public static bool
      IsStaging(this IHostEnvironment hostEnvironment) =>
      hostEnvironment.IsEnvironment(Environments.Staging); }public static class
      Environments {public static readonly string Development = "Development"; public
      static readonly string Production = "Production"; public static readonly string
      Staging ="Staging"; }
      從某種意義上講,這也體現(xiàn)了.NET Core Hosting System在設(shè)計(jì)上的一個(gè)問題,希望在以后的版本中能夠解決這個(gè)問題。

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          少妇被多人c夜夜爽爽av | 美女免费网站 | 污网站18 | 翔田千里无码破解版 | 日韩一级A片免费 | 色人人操 | 精品一区二区三区鸳鸯网 | 欧美日韩在线播放 | 长泽梓黑人初解禁bdd07 | 吃奶舔下面 |