<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [C#]BeforeFieldInit 與類靜態(tài)構(gòu)造函數(shù)

      BeforeFieldInit 與類靜態(tài)構(gòu)造函數(shù)

      羅朝輝 (http://kesalin.cnblogs.com/)

      本文遵循“署名-非商業(yè)用途-保持一致”創(chuàng)作公用協(xié)議

      如下代碼:

      using System;
      namespace BeforeFieldInit
      {
          internal class Foo
          {
              Foo(){ Console.WriteLine("Foo 對象構(gòu)造函數(shù)");}
              public static string Field = GetString("初始化 Foo 靜態(tài)成員變量!");
      
              public static string GetString(string s){
                  Console.WriteLine(s);
                  return s;
              }
          }
      
          internal class FooStatic
          {
              static FooStatic(){ Console.WriteLine("FooStatic 類構(gòu)造函數(shù)"); }
              FooStatic(){ Console.WriteLine("FooStatic 對象構(gòu)造函數(shù)"); }
      
              public static string Field = GetString("初始化 FooStatic 靜態(tài)成員變量!");
              public static string GetString(string s){
                  Console.WriteLine(s);
                  return s;
              }
          }
      
          class Program
          {
             static void Main(string[] args){
                  Console.WriteLine("Main 開始 ...");
      
                  Foo.GetString("手動調(diào)用 Foo.GetString() 方法!");
                  //string info = Foo.Field;
      
                  FooStatic.GetString("手動調(diào)用 FooStatic.GetString() 方法!");
                  //string infoStatic = FooStatic.Field;
      
                  Console.ReadLine();
              }
          }
      }

      Foo 和 FooStatic 唯一的不同就是 FooStatic 有靜態(tài)的類構(gòu)造函數(shù)。執(zhí)行上面的代碼,輸出如下:

      如果把被注釋的讀取靜態(tài)字段Field的兩行代碼打開,再編譯運行,輸出:

      對比上面的區(qū)別,F(xiàn)ooStatic 始終是延遲裝載的,也就是只有類被首次使用時,類對象才被構(gòu)造,其靜態(tài)成員以及靜態(tài)構(gòu)造函數(shù)才被初始化執(zhí)行, 而 Foo 類對象的初始化則交給 CLR 來決定。

      如果用 IL Dasm.exe對比兩個類生成的中間代碼,可以看到只有一處不同:FooStatic 比 Foo 少了一個特性:beforefieldinit。

      也就是說靜態(tài)構(gòu)造函數(shù)抑制了 beforefieldinit 特性,而該特性會影響對調(diào)用該類的時機。

      C# 里面的靜態(tài)構(gòu)造函數(shù),也稱為類型構(gòu)造器,類型初始化器,它是私有的,就是在上圖中的 .cctor : void()。CLR保證一個靜態(tài)構(gòu)造函數(shù)在每個AppDomain中只執(zhí)行一次,而且這種執(zhí)行是線程安全的,所以在靜態(tài)構(gòu)造函數(shù)中非常適合于單例模式的初始化(初始化靜態(tài)字段等同于在靜態(tài)構(gòu)造函數(shù)中初始化,但不完全相同,因為顯式定義靜態(tài)構(gòu)造函數(shù)會抑制beforefieldinit標志。)。

      JIT編譯器在編譯一個方法時,會查看代碼中引用了哪些類型,任何一個類型定義了靜態(tài)構(gòu)造函數(shù),JIT編譯器都會檢查針對當前 AppDomain,是否執(zhí)行了這個靜態(tài)構(gòu)造函數(shù)。如果類型構(gòu)造去沒有執(zhí)行,JIT編譯器就會在生成的本地代碼中添加對靜態(tài)構(gòu)造函數(shù)的一個調(diào)用,否則就不會添加,因為類型已經(jīng)初始化。同時CLR還保證在執(zhí)行本地代碼中生成的靜態(tài)構(gòu)造函代碼的線程安全。

      根據(jù)上面的描述,我們知道 JIT 必須決定是否生成類型靜態(tài)構(gòu)造函數(shù)代碼,還須決定何時調(diào)用它。具體在何時調(diào)用有兩中方式:

      precise:JIT編譯器可以剛好在創(chuàng)建類型的第一個實例之前,或剛好在訪問類的一個非繼承的字段或成員之前生產(chǎn)這個調(diào)用。

      beforefieldinit:JIT編譯器可以在首次訪問一個靜態(tài)字段或者一個靜態(tài)/實例方法之前,或者創(chuàng)建類型的第一個實例之前,隨便找一個時間生成調(diào)用。具體調(diào)用時機由CLR決定,它只保證訪問成員之前會執(zhí)行靜態(tài)構(gòu)造函數(shù),但可能會提前很早就執(zhí)行。

      CLI specification (ECMA 335) 在 8.9.5 節(jié)中提到:

      1. If marked BeforeFieldInit then the type's initializer method is executed at, or sometime before, first access to any static field defined for that type
      2. If not marked BeforeFieldInit then that type's initializer method is executed at (i.e., is triggered by):
      • first access to any static or instance field of that type, or
      • first invocation of any static, instance or virtual method of that type

      簡單點說就是beforefieldinit可能會提前調(diào)用一個類型的靜態(tài)構(gòu)造函數(shù),而precise模式是非要等到用時才調(diào)用類型的靜態(tài)構(gòu)造函數(shù),它是嚴格的延遲裝載。

      beforefieldinit 是首選的(如果沒有自定義靜態(tài)構(gòu)造函數(shù),默認就是這種方式),因為它使CLR能夠自由選擇調(diào)用靜態(tài)構(gòu)造函數(shù)的時機,而CLR會盡可能利用這一點來生成運行得更快的代碼。比如說在一個循環(huán)中調(diào)用單例(且包含首次調(diào)用),beforefieldinit方式可以讓CLR決定在循環(huán)之前就調(diào)用靜態(tài)構(gòu)造函數(shù)來優(yōu)化,而precise模式則只會在循環(huán)體中來調(diào)用靜態(tài)構(gòu)造函數(shù),并在之后的調(diào)用會檢測靜態(tài)構(gòu)造函數(shù)是否已被執(zhí)行的標志位,這樣效率稍低一些。在前面使用靜態(tài)Field的情況下,beforefieldinit 方式下CLR也認為提前執(zhí)行靜態(tài)構(gòu)造函數(shù)是更好的選擇。

      C# 的單例實現(xiàn),可以利用 precise 延遲調(diào)用這一點來延遲對單例對象的構(gòu)造(餓汗模式),從而帶來一丁點的優(yōu)化,但是在絕大部分情況下這一丁點的優(yōu)化作用并不大!

      posted @ 2012-05-10 12:21  飄飄白云  閱讀(1308)  評論(0)    收藏  舉報
      本博客遵循 Creative Commons License “署名-非商業(yè)用途-保持一致”創(chuàng)作共用協(xié)議。 與我聯(lián)系
      主站蜘蛛池模板: 老色99久久九九爱精品| 人人澡人摸人人添| 国产欧美日韩亚洲一区二区三区| 国厂精品114福利电影免费| 久久天天躁狠狠躁夜夜2020老熟妇 | 亚洲国产成人午夜在线一区| 天堂网在线观看| 国产婷婷综合在线视频中文| 国精产品一区一区三区有限公司杨 | 蜜桃臀av在线一区二区| 性色欲情网站iwww| 国产亚洲精品成人aa片新蒲金| 久久国产精品成人免费| 日韩熟女熟妇久久精品综合| 成年女人免费碰碰视频| 亚洲色大成网站WWW久久| 亚洲国产日韩一区三区| 日韩伦理片| a4yy私人毛片| 玛沁县| 国产精品入口中文字幕| 国产偷窥熟女高潮精品视频| 高清偷拍一区二区三区| A级毛片100部免费看| 强奷漂亮人妻系列老师| 漂亮的人妻不敢呻吟被中出| Y111111国产精品久久久| 亚洲人成亚洲人成在线观看| 成人年无码av片在线观看| 舟曲县| 亚洲人成人一区二区三区| 宝贝腿开大点我添添公视频免| 波多野结衣一区二区三区高清av| 亚洲春色在线视频| 二区三区国产在线观看| 亚洲国产日韩a在线亚洲| 久久精品国产亚洲av忘忧草18| 国产精品毛片av999999| 凹凸国产熟女精品视频| 九九热视频在线观看视频| 国产亚洲人成网站在线观看|