亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#基本知識點-Readonly和Const的區別

2019-11-14 16:14:52
字體:
來源:轉載
供稿:網友

目錄

  • 什么是靜態常量(Const)和動態常量(Readonly)
  • 靜態常量(Const)和動態常量(Readonly)之間的區別
  • 動態常量(Readonly)被賦值后不可以改變
  • 總結

什么是靜態常量(Const)和動態常量(Readonly)

  先解釋下什么是靜態常量(Const)以及什么是動態常量(Readonly)。
  靜態常量(Const)是指編譯器在編譯時候會對常量進行解析,并將常量的值替換成初始化的那個值。
  動態常量(Readonly)的值則是在運行的那一刻才獲得的,編譯器編譯期間將其標示為只讀常量,而不用常量的值代替,這樣動態常量不必在聲明的時候就初始化,而可以延遲到構造函數中初始化。

靜態常量(Const)和動態常量(Readonly)之間的區別

 

靜態常量(Compile-time Constant)

動態常量(Runtime Constant)

定義

聲明的同時要設置常量值。

聲明的時候可以不需要進行設置常量值,可以在類的構造函數中進行設置。

類型限制

只能修飾基元類型,枚舉類型或者字符串類型。

沒有限制,可以用它定義任何類型的常量。

對于類對象而言

對于所有類的對象而言,常量的值是一樣的。

對于類的不同對象而言,常量的值可以是不一樣的。

內存消耗

無。

要分配內存,保存常量實體。

綜述

性能要略高,無內存開銷,但是限制頗多,不靈活。

靈活,方便,但是性能略低,且有內存開銷。

  1. Const修飾的常量在聲明的時候必須初始化;Readonly修飾的常量則可以延遲到構造函數初始化 。
  2. Const常量既可以聲明在類中也可以在函數體內,但是Static Readonly常量只能聲明在類中。Const是靜態常量,所以它本身就是Static的,因此不能手動再為Const增加一個Static修飾符。
  3. Const修飾的常量在編譯期間就被解析,即:經過編譯器編譯后,我們都在代碼中引用Const變量的地方會用Const變量所對應的實際值來代替; Readonly修飾的常量則延遲到運行的時候。

  舉個例子來說明一下:

        public static readonly int NumberA = NumberB * 10;        public static readonly int NumberB = 10;        public const int NumberC = NumberD*10;        public const int NumberD = 10;        static void Main(string[] args)        {            Console.WriteLine("NumberA is {0}, NumberB is {1}.", NumberA, NumberB);//NumberA is 0, NumberB is 10.            Console.WriteLine("NumberC is {0}, NumberD is {1}.", NumberC, NumberD);//NumberC is 100, NumberD is 10.            Console.ReadKey();        }
View Code

  以上是語法方面的應用,那在實際的用法上,還是有些微妙的變化,通常不易發覺.
  舉個例子來說明一下:
  在程序集DoTestConst.dll 中有一個類MyClass,定義了一個公開的靜態變量Count

    public static class MyClass    {        public const int Count = 10;    }

  然后另外一個應用程序中引用DoTestConst.dll,并在代碼中作如下調用:

    public static void Main(string[] args)    {        Console.WriteLine(DoTestConst.MyClass.Count);//輸出10        Console.ReadKey();    }

  毫無疑問,非常簡單的代碼,直接輸出10。
  接下來更新MyClass的Count的值為20,然后重新編譯DoTestConst.dll,并更新到應用程序的所在目錄中,注意不要編譯應用程序。那么這時候的輸出結果按預期那么想應該是20才對,但實際上還是10,為什么呢?
  這就是Const的特別之處,有多特別還是直接看生成的IL,查看IL代碼(假設這時候Count的值為10)

  IL_0000: nop
  IL_0001: ldc.i4.s 10
  IL_0003: call void [mscorlib]System.Console::WriteLine(int32)

  紅色代碼很明顯的表明了,直接加載10,沒有通過任何類型的加載然后得到對應變量的,也就是說在運行時沒有去加載DoTestConst.dll,那么是否意味著沒有DoTestConst.dll也可以運行呢?答案是肯定的,刪除DoTestConst.dll也可以運行,是否很詭異呢?也就解釋了之前的實驗,為什么更新Const變量的值之后沒有調用新的值,因為程序在運行的時候根本不會去加載DoTestConst.dll。那么10這個值是從哪來的呢?實際上CLR對于Const變量做了特殊處理,是將Const的值直接嵌入在生成的IL代碼中,在執行的時候不會再去從dll加載。這也帶來了一個不容易發覺的Bug,因此在引用其他程序集的Const變量時,需考慮到版本更新問題,要解決這個問題就是把調用的應用程序再編譯一次就ok了。但實際程序部署更新時可能只更新個別文件,這時候就必須用Readonly關鍵字來解決這個問題。

  接下來看Readonly的版本:

    public static class MyClass    {        public static readonly int Count = 10;    }

  調用方代碼不變,接著看生成的IL代碼:

  IL_0000: nop
  IL_0001: ldsfld int32 [DoTestConst]DoTestConst.MyClass::Count
  IL_0006: call void [mscorlib]System.Console::WriteLine(int32)

  很明顯加載代碼變了,一個很常見的ldsfld動作,請求了DoTestConst.MyClass的Count變量,是通過強制要求加載DoTestConst來實現的。因此這時候更新Count的值重新編譯之后,還是不編譯調用程序,然后再執行就會看到新的值。而這時候如果刪除DoTestConst.dll那么,會出現找不到dll之類的異常。這也充分說明了對于Readonly定義的變量是在運行時加載的。

動態常量(Readonly)被賦值后不可以改變

  ReadOnly 變量是運行時變量,它在運行時第一次賦值后將不可以改變。其中“不可以改變”分為兩層意思:

  1. 對于值類型變量,值本身不可以改變(Readonly, 只讀)
  2. 對于引用類型變量,引用本身(相當于指針)不可改變。

  值類型變量,舉個例子說明一下:

    public class Student    {        public readonly int Age;        public Student(int age)        {            this.Age = age;        }    }

  Student的實例Age在構造函數中被賦值以后就不可以改變,下面的代碼不會編譯通過:

Student student = new Student(20);student.Age = 21; //錯誤信息:無法對只讀的字段賦值(構造函數或變量初始化器中除外)

  引用類型變量,舉個例子說明一下:

    public class Student    {        public int Age; //注意這里的Age是沒有readonly修飾符的        public Student(int age)        {            this.Age = age;        }    }    public class School    {        public readonly Student Student;        public School(Student student)        {            this.Student = student;        }    }

  School實例的Student是一個引用類型的變量,賦值后,變量不能再指向其他任何的Student實例,所以,下面的代碼將不會編譯通過:

School school = new School(new Student(10));school.Student = new Student(20);//錯誤信息:無法對只讀的字段賦值(構造函數或變量初始化器中除外)

  引用本身不可以改變,但是引用說指向的實例的值是可以改變的。所以下面的代碼是可以編譯通過的:

School school = new School(new Student(10));school.Student.Age = 20;

  在構造方法中,我們可以多次對Readonly修飾的常量賦值。舉個例子說明一下:

    public class Student    {        public readonly int Age = 20;//注意:初始化器實際上是構造方法的一部分,它其實是一個語法糖        public Student(int age)        {            this.Age = age;            this.Age = 25;            this.Age = 30;        }    }

總結

  Const和Readonly的最大區別(除語法外)
  Const的變量是嵌入在IL代碼中,編譯時就加載好,不依賴外部dll(這也是為什么不能在構造方法中賦值)。Const在程序集更新時容易產生版本不一致的情況。
Readonly的變量是在運行時加載,需請求加載dll,每次都獲取最新的值。Readonly賦值引用類型以后,引用本身不可以改變,但是引用所指向的實例的值是可以改變的。在構造方法中,我們可以多次對Readonly賦值。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人在线一区| 欧美精品性视频| 日本精品免费观看| 亚洲激情久久久| 欧美久久精品一级黑人c片| 亚洲精品久久久久久久久久久久| 国产a级全部精品| 国产精品一区二区三区免费视频| 久久青草精品视频免费观看| 成人在线激情视频| 国产精品亚洲综合天堂夜夜| 久久久亚洲网站| 色香阁99久久精品久久久| 成人综合国产精品| 久久男人av资源网站| 国产精品入口免费视频一| 18久久久久久| 国产精品久久久久影院日本| 性色av一区二区三区红粉影视| 日韩中文字幕视频在线观看| 亚洲精品中文字幕有码专区| 超薄丝袜一区二区| 欧美成人精品不卡视频在线观看| 久久999免费视频| 亚洲精品久久久一区二区三区| 欧美激情视频在线| 日韩成人在线视频| 国产精品视频专区| 亚洲最新av在线| 久久人人爽人人| 中文字幕亚洲图片| 日韩综合中文字幕| 精品国产电影一区| 亚洲高清久久久久久| 欧美日韩激情网| 98精品国产高清在线xxxx天堂| 秋霞成人午夜鲁丝一区二区三区| 欧美激情亚洲精品| 中文字幕一区日韩电影| 欧美电影免费观看高清完整| 国产成人一区二区| 精品久久国产精品| 久久中文字幕在线| 色多多国产成人永久免费网站| 亚洲欧美日韩天堂一区二区| 欧美在线视频观看| 欧美夫妻性视频| 亚洲欧洲国产伦综合| 欧美日产国产成人免费图片| 国产成人在线一区| 国产精品视频午夜| 国产高清视频一区三区| 久久久在线免费观看| 国语自产在线不卡| 欧美有码在线视频| 国产精品96久久久久久| 欧美日韩一区二区三区| 国产精品电影在线观看| 色综合导航网站| 国产精品一区久久久| 欧美性视频精品| 国产欧亚日韩视频| 色哟哟网站入口亚洲精品| 日韩视频在线免费观看| 欧美专区日韩视频| 久久成年人免费电影| 久久综合免费视频| 在线性视频日韩欧美| 欧美成人亚洲成人日韩成人| 91精品国产成人| 欧美日韩国产精品一区| 亚洲黄色av网站| 亚洲黄色片网站| 国产亚洲精品高潮| 大桥未久av一区二区三区| 亚洲男人天堂2024| 操人视频在线观看欧美| 操人视频在线观看欧美| 国产精品十八以下禁看| 国产亚洲日本欧美韩国| 欧美视频13p| 在线午夜精品自拍| 国产脚交av在线一区二区| 久久伊人精品视频| 亚洲人成77777在线观看网| 在线日韩中文字幕| 久久成人18免费网站| 久久久久成人网| 中文字幕无线精品亚洲乱码一区| 日韩精品极品视频免费观看| 日韩免费中文字幕| 亚洲欧洲av一区二区| 亚洲欧美日韩一区在线| 91亚洲va在线va天堂va国| 国产69精品久久久久久| 国产精品99久久久久久白浆小说| 国产精品视频99| 国产精品高潮在线| 日韩一区二区三区在线播放| 夜夜嗨av一区二区三区免费区| 国产精品狠色婷| 91a在线视频| 久久成年人视频| 久久精品国产成人精品| 午夜精品一区二区三区在线播放| 日韩美女视频免费在线观看| 欧美性猛交xxxx久久久| 在线播放亚洲激情| 亚洲最大的免费| 国产精品一香蕉国产线看观看| 国产精品激情自拍| 高清欧美性猛交xxxx| 日韩中文在线观看| 国产精品国产三级国产专播精品人| 国产成人精品亚洲精品| 伊人久久久久久久久久久久久| 日韩免费观看在线观看| 国产精品美乳在线观看| 91精品国产91久久久久久最新| 国内外成人免费激情在线视频网站| 欧美高清激情视频| 97超碰蝌蚪网人人做人人爽| 国产成人久久久| 在线看福利67194| 国产va免费精品高清在线| 欧美另类69精品久久久久9999| 自拍偷拍亚洲在线| 国产精品久久激情| 国产69久久精品成人看| 国产精品亚洲激情| 精品无人区太爽高潮在线播放| 亚洲xxxx在线| 日韩资源在线观看| 欧美有码在线观看视频| 亚洲欧美国内爽妇网| 91精品视频免费观看| 欧美二区乱c黑人| 成人国产精品色哟哟| 亚洲日韩中文字幕| 91久久精品国产91久久性色| 日韩中文字幕网站| 久久好看免费视频| 久久亚洲欧美日韩精品专区| 日韩精品黄色网| 成人欧美一区二区三区黑人| 日韩理论片久久| 亚洲精品久久久久中文字幕二区| 国产精品久久久久久亚洲调教| 国产日韩欧美黄色| 国产亚洲视频在线观看| 日韩亚洲精品视频| 亚洲资源在线看| 亚洲欧美日韩精品久久亚洲区| 欧美亚洲免费电影| 欧美另类交人妖| 欧美最猛性xxxxx(亚洲精品)| 国产亚洲精品va在线观看| 欧美极品少妇全裸体| 亚洲白虎美女被爆操| 精品中文字幕乱| 欧美高清在线视频观看不卡| 亚洲男女自偷自拍图片另类| 在线观看成人黄色| 精品视频在线观看日韩|