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

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

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

      探索系列:深入辨析 ReadOnly,Const


            Last time when I was asked what is the diff between Readonly and ConstI was really ashamed that I said don’t know on explaining the exact difference between this two simple key word…

      過后,特意研究了下這兩個關(guān)鍵字究竟有何不同:

       

      首先,從CLI中對CTSType的規(guī)定說起。在第四版本的ECMA-355CLI標(biāo)準(zhǔn)中,規(guī)定的對于每一個Type,都可以包含很多成員。所有的成員(members),一共可以有三種:第一種叫做fields,它是定義的和這個類型相關(guān)的存儲單元。第二中成員類型就是我們熟悉的方法(Method)。第三中,叫做nested type。也就是嵌套類型,對于每一個type里面,都可以包含對于別的type的聲明和使用。

      對于所有的成員,又可以分為兩種:per-type memberper-instance member。顧名思義,前一種,是對于每一個type只有一個的成員,譬如static修飾的field。后一種,是對于每一個運行時候的實例,都保持一個不同的實現(xiàn)版本。

      對于其他的類型的成員,包括我們熟知的PropertiesEvents之類,這些反編譯成為IL語言之后可以看到,全部直接的,或者是間接的轉(zhuǎn)換成為了方法。

       

      有的時候,我們需要一個field在它的整個生命周期里面,它所包含的這個值是不改變的。這個時候,根據(jù)這個變量被賦值的不同的情況,CLR為提供了兩種技術(shù)來實現(xiàn)這種要求:

      第一種,field里面包含的值,可以在編譯的時候被計算出來。就是const關(guān)鍵字聲明的變量。這種方法的實現(xiàn)效率是最高的。這個值,是作為一個字面上的固定的值,保存在包含這個typemodule文件的metadata里面。Const定義的這個值,可以是一個表達式,但是這個表達式的結(jié)果,必須是編譯的時候可以計算出來的。這樣,在編譯的時候,就可以植入到其余的指令里面去。

      Const定義的field,必須在定義的時候,就給初始化了,而且,一旦初始化了之后,就不能再改變它的值。同時,不能聲明一個constfieldstatic,因為,const定義的field就表明這個field是一個static的。

      任何對const定義的常量的修改,都會拋出一個編譯時錯誤。

      我們可以把const修飾的field,歸類到memberper-type member里面去。

      第二種,是被readonly修飾的fieldReadonly修飾的常量,可能是因為,有的時候,我們需要一些field,它的值是不應(yīng)該改變的,但是,在運行之前,是不知道這個值的,這個時候,就可以用readonly來修飾這個field

      這個readonly修飾的field,就為常量這個名詞提供了另外一種靈活得多的解決方案了。首先,它的值,是可以在運行的時候,根據(jù)別的變量動態(tài)計算出來的,而const修飾的常量的值就不能這樣了。同時,不同于const,它是一個per-instance member。也就是說,對于每一個實例,它都可以保存一個不同的實現(xiàn)版本,而const就不行了。對于某一個type的所有的實現(xiàn)實例,const定義的field,只能有一個不變的值。

       

      寫到這里,從原理的角度已經(jīng)闡述的比較清楚了,接著用一個實例來分析下:

          class Program

          {

              public const int conField=122*1119;

              public readonly int roField;

              private int _property;

              public int Property

              {

                  get

                  {

                      return _property;

                  }

                  set

                  {

                      _property = value;

                  }

              }

       

              static void Main(string[] args)

              {

                  (new Program()).Method();

              }

      }

      Diassemble之后,得到下面的顯示結(jié)果:

      .namespace TestConcoleApp

      {

        .class private auto ansi beforefieldinit Program

             extends [mscorlib]System.Object

        {

             //這里可以看到,一個const定義的一個field,是literal,并且被static關(guān)鍵字來修飾。同時,在編譯的時候,就計算得到了這個field的值。

          .field public static literal int32 conField = int32(136518)

             //readonly關(guān)鍵字修飾的field,只是被用initonly來修飾,per-instance類型。

          .field public initonly int32 roField

          .field private int32 _property

             //在程序的屬性里面定義的get關(guān)鍵字,最終在這里被轉(zhuǎn)換成為了一個方法來處理。

          .method public hidebysig specialname instance int32 get_Property() cil managed

          {

            .maxstack 1

            .locals init (int32)

       

            IL_0000:  nop       

            IL_0001:  ldarg.0   

            IL_0002:  ldfld      int32 TestConcoleApp.Program::_property

            IL_0007:  stloc.0   

            IL_0008:  br.s       IL_000a

            IL_000a:  ldloc.0   

            IL_000b:  ret       

          }

             //對上面的一個Propertyset動作,最終在這里轉(zhuǎn)化成為了一個方法

          .method public hidebysig specialname instance void set_Property(int32 'value') cil managed

          {

            .maxstack 8

           

            IL_0000:  nop        

            IL_0001:  ldarg.0   

            IL_0002:  ldarg.1   

            IL_0003:  stfld      int32 TestConcoleApp.Program::_property

            IL_0008:  ret       

          }

       

          .method private hidebysig static void Main(string[] args) cil managed

          {

            .entrypoint

            .maxstack 8

           

            IL_0000:  nop       

            IL_0001:  newobj     instance void TestConcoleApp.Program::.ctor()

            IL_000b:  nop       

            IL_000c:  ret       

          }

       

          .method public hidebysig specialname rtspecialname instance void .ctor() cil managed

          {

            .maxstack 8

           

            IL_0000:  ldarg.0   

            IL_0001:  call       instance void [mscorlib]System.Object::.ctor()

            IL_0006:  ret       

          }

             //這里用property來表示一個屬性,實際上是轉(zhuǎn)換成為了兩個方法來操作一個private修飾的field

          .property instance int32 Property()

          {

            .get instance int32 TestConcoleApp.Program::get_Property()

            .set instance void TestConcoleApp.Program::set_Property(int32)

          }

        }

      }

       

      再看了readonlyconst被編譯成為IL的代碼之后,對這兩個關(guān)鍵字到底是如何運作,有什么區(qū)別和相同的地方,又有了進一步的確認和了解。

       

      后記:

      其實,我還想驗證一下,public const int conField=122*1119;這一句中122*1119的結(jié)果,在作為一個module的時候,是計算好了保存在一個擴展了的DotNet下的PE文件的Metadata里面,然后在驗證一下,運行的時候,一個type有多個實例,而const定義的field只有一個的。

      不過動用了一大批調(diào)試工具和托管模塊結(jié)構(gòu)查看工具,把PE格式文件里面的元數(shù)據(jù)表狠狠的都刨了一遍,也沒找到這個值。在這個文件執(zhí)行的時候,windbg attach到這個進程,把這個模塊在的內(nèi)存刨了一個遍,還是沒找到這個常量具體的location….郁悶壞了

      先就整理到這里吧,改天好好的分析下PE文件格式里面的元數(shù)據(jù)表和托管進程的內(nèi)存布局。

            

      后記補記:

      今天,又把metadata的幾種表結(jié)構(gòu)的reference看了看,把上面生成的那個托管模塊里里外外又刨了一次,用dumpbin+ildasm,在查看元數(shù)據(jù)表的時候,終于找到了上面用readonlyconst定義的兩個字段在元數(shù)據(jù)里面的表示:

             Field #1 (04000001)

             -------------------------------------------------------

                    Field Name: conField (04000001)

                    Flags     : [Public] [Static] [Literal] [HasDefault]  (00008056)

             DefltValue: (I4) 136518

                    CallCnvntn: [FIELD]

                    Field type:  I4

       

             Field #2 (04000002)

             -------------------------------------------------------

                    Field Name: roField (04000002)

                    Flags     : [Public] [InitOnly]  (00000026)

                    CallCnvntn: [FIELD]

                    Field type:  I4

             可以看到,在編譯成為托管模塊的時候,這個const定義的變量就被計算了出來,把值136518已經(jīng)保存到了托管PE文件的元數(shù)據(jù)表里面。并且,還有staticliteralhasdefault這幾個關(guān)鍵字來修飾。而readonly修飾的field,只有一個initonly來修飾。



            
      到這里,終于給這段刨根問底readonlyconst關(guān)鍵字的文章畫上了一個比較完整的句號吧。

      posted on 2007-12-23 00:38  lbq1221119  閱讀(1244)  評論(5)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 国产乱码一区二区三区| 亚洲国产精品日韩在线| 亚洲av午夜成人片| 国产精品爽爽久久久久久竹菊| 青春草公开在线视频日韩| 精品尤物TV福利院在线网站| 国产亚洲国产精品二区| 国产对白老熟女正在播放| 精品人妻少妇嫩草av系列| 久久夜色撩人精品国产小说| 欧美日韩亚洲国产| 91精品乱码一区二区三区| 国产乱老熟女乱老熟女视频| 狠狠五月深爱婷婷网| 亚洲欧美高清在线精品一区二区| 婷婷色香五月综合缴缴情香蕉 | 成人亚洲性情网站www在线观看| 人妻久久久一区二区三区| 國产AV天堂| 亚洲综合av男人的天堂| 亚洲一级特黄大片一级特黄| 丰满少妇高潮无套内谢| 国产色a在线观看| 国产高清在线男人的天堂| 丝袜高潮流白浆潮喷在线播放| 久久精品国产99麻豆蜜月| 国产综合精品一区二区三区| 成人中文在线| 毛片无遮挡高清免费| 国产日韩乱码精品一区二区| 国产精品视频中文字幕| 熟女人妻精品一区二区视频| 中文字幕日韩有码一区| 国产不卡一区不卡二区| 日本高清视频网站www| 白朗县| 国产h视频在线观看| 永久免费观看美女裸体的网站| 天天看片视频免费观看| 欧美牲交a欧美牲交aⅴ一| 久久成人伊人欧洲精品|