2017年7月17日 星期一

[C#]const, static readonly


  • const
    • 編譯期間就確定
    • 因此只能宣告通過常量表達式來指定值
  • static readonly
    • 宣告時可不強制初始值,但宣告 readonly 之後不能再給值,所以一般宣告 static readonly 時一定會給初始值,不過其初始值是可變
    • 運行時計算的值,所以可以通過靜態結構函數來賦值
    • Reference類型,只是被限定不能進行賦值(寫入)操作。其它成員的讀寫仍然是不受限制
      • Code
        
        public static readonly MyClass myins = new MyClass();
        /// 
        /// 正常
        /// 
        myins.SomeProperty = 10;
        /// 
        /// 錯誤,該物件只能讀取
        /// 
        myins = new MyClass();
    • 如上中的 MyClass 不是 class 而是 struct,後面的兩個語句都會出錯
  • const and static readonly
    • 唯讀變數
    • 系統啟動時就存在,其生命週期等同Application變數
      • Code
      
      /// 
      /// 1.不可以換成 const,new 超作需要執行建構函数,所以無法在編譯期間確定
      /// 
      static readonly MyClass myins = new MyClass();
      /// 
      /// 2.不可以換成 const,理由跟 1 一樣,雖然 1,2,3 的數組是一個常量
      /// 
      static readonly int [] constIntArray = new int[] {1, 2, 3};
      /// 
      /// 3.可以換成 const,Reference 類型的常量(除了String)只能是 Null
      /// 
      static readonly MyClass myins = null;
      /// 
      /// 3.可以換成 const,可在編譯期間很明確,A等於200
      /// 
      static readonly A = B * 20;
      static readonly B = 10;
      /// 
      /// 5.不可以換成 readonly,readonly 只能用來修飾類 field,不能修飾局部變量,也不能修飾 property 等其它類成員
      /// 
      void SomeFunction()
      {
          const int a = 10;
      }
    • 對於那些本質上應該是常量,但是卻無法使用const來聲明的地方,可以使用static readonly
      • Code
      
      public class Color
      {
          public static readonly Color Black = new Color(0, 0, 0);
          public static readonly Color White = new Color(255, 255, 255);
          public static readonly Color Red = new Color(255, 0, 0);
          public static readonly Color Green = new Color(0, 255, 0);
          public static readonly Color Blue = new Color(0, 0, 255);
      
          private byte red, green, blue;
      
          public Color(byte r, byte g, byte b)
          {
              red = r;
              green = g;
              blue = b;
          }
      }
  • const and static readonly different 1
    • static readonly
      • Code
      
      using System;
      class Demo
      {
          static readonly int A = B * 10;
          static readonly int B = 10;   
          public static void Main(string[] args)
          {
              Console.WriteLine("A is {0},B is {1} ", A, B);
          }
      }
      • 輸出結果是 A is 0, B is 10
    • const
      • Code
      
      using System;
      class Demo
      {
          const int A = B * 10;
          const int B = 10;   
          public static void Main(string[] args)
          {
              Console.WriteLine("A is {0},B is {1} ", A, B);
          }
      }
      • 輸出結果是 A is 100, B is 10
    • const 是靜態常量,所以在編譯時候就將 A 與 B 的值確定 ( B 值為 10,而 A = B * 10 為 100 ) ,因此輸出當然為 A is 100, B is 10
    • static readonly 為動態常量,變量值在編譯期間不予解析,所以開始都是默認值,因 A 與 B 都是 int 類型,初始值為 0。而程序執行到 A = B * 10; 所以 A = 0 * 10 為 0,程序接著執行到 B = 10 時候,才會真正初始 B 的值,將 10 賦給 B
  • const and static readonly different 2
    • static readonly
      • Code
      
      /// 
      /// 正確:初始值是可變
      /// 
      static readonly int delayMonth = DateTime.Now.Month;
      

    • const
      • Code
      
      /// 
      /// 正確
      /// 
      const int delayMonth = 1;
      /// 
      /// 錯誤:因為 DateTime.Now. 是可變,如:本月是7,但下個月是8,常數必須是明確固定值,而不是隨著外在因素變動 
      /// 
      const int delayMonth = DateTime.Now.Month;
    • 兩個特性作比較,switch 陳述式必須不可變動值才能作 case 動作,所以 static readonly 並不適用,只能使用 const 變數
  • REF
    • http://www.cnblogs.com/wangshenhe/archive/2012/05/16/2503831.html
    • https://dotblogs.com.tw/kim/2009/05/11/const
    • https://msdn.microsoft.com/zh-tw/library/aa645753(v=vs.71).aspx

沒有留言:

張貼留言