C# const 和 readonly 有什麼區別

在寫常量的時候,是選擇使用 const 還是 static readonly 是一個讓人難以決定的問題,本文告訴大家這兩個方法的區別。

如果一個類有靜態字段,會如何初始化

可以使用的方法有兩個,第一個方法就是直接在屬性定義時寫創建,第二個方法就是在構造創建,請看下面代碼

    private static Test _test = new Test();
    private static Test _test;
    static Demo()
    {
        _test = new Test();
    }

再來思考下面的問題

請看下面兩個代碼有什麼區別

    const string str = "xxxxx";
    static readonly string str = "xxxxx";
  • const 編譯時常量
  • static readonly 運行時常量

修改兩常量的值,生成新的Test.dll,然後運行Demo.exe(不編譯)。

在不重新編譯運行的時候,從上面的輸出可以看到,使用const的值是不會修改,具體原因是因爲 const 會被內聯到代碼

如寫了下面的代碼

        public void DeawelTurkisHotarwoWefudaybem()
        {
            var str = "德熙" + Foo;
        }

        private const string Foo = "逗";

這時使用 Resharper 的 ILViewer ,在 Resharper 的 Resharper->Windows->ILViewer 打開,重新編譯一下項目,把光標放在var str = "德熙" + Foo就可以看到類似下面代碼的 IL 顯示的是拼接了"德熙" + Foo的字符串

  .method public hidebysig instance void 
    DeawelTurkisHotarwoWefudaybem() cil managed 
  {
    .maxstack 1
    .locals init (
      [0] string str
    )

    // [8 9 - 8 10]
    IL_0000: nop          

    // [9 13 - 9 34]
    IL_0001: ldstr        "德熙逗"
    IL_0006: stloc.0      // str

    // [10 9 - 10 10]
    IL_0007: ret          

  }

如果是方法內的常量也是會被內聯代碼,請看下面代碼

        public void DeawelTurkisHotarwoWefudaybem()
        {
            const int n = 100;
            var foo = n;
        }

這時從 IL 可以創建的是下面的代碼,定義的 n 是不存在的

  .method public hidebysig instance void 
    DeawelTurkisHotarwoWefudaybem() cil managed 
  {
    .maxstack 1
    .locals init (
      [0] int32 foo
    )

    // [9 9 - 9 10]
    IL_0000: nop          

    // [11 13 - 11 25]
    IL_0001: ldc.i4.s     100 // 0x64
    IL_0003: stloc.0      // foo

    // [12 9 - 12 10]
    IL_0004: ret          

  }

上面代碼的IL_0001就是把一個int壓入棧,壓入的值是 100 ,也就是原來的定義的 n 就被去掉了,直接使用n的值

如果dll被其他100個工程引用的話, 每次修改 Test 的 const 變量後一定要重新 build 這100個工程, 不然的話這些工程裏的const值就不會更新。

1.編譯時常量更改時,引用該常量的程序集必須重新編譯, 才能獲取已更新的值。

2.運行時常量更改時,引用該常量的程序集不必重新編譯,直接運行便可獲得已更新的值。

對於隱式轉換,如果是 const 支持隱式轉換,如果是static readonly,不支持

(1)const常量在編譯時解析;而static readonly常量在運行時解析。

(2)const常量必須在定義時初始化;而static readonly常量可以在定義時初始化,也可以在構造函數中初始化;

(3)非常確定不會改變的常量值可以用const,必須寫在函數體內的常量需要用const,需要被attributes用到的常量應該用const。

(4)常量需要被客戶端引用,且可能會改變,應該用static readonly。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章