C# const和static readonly區別

[轉]C# const和static readonly區別

之前只是知道Const和static readonlyd的區別在於const的值是在編譯期間肯定的,而static readonly是在運行時計算出其值的。今天看到Resharper智能提示讓用html

static readonly修飾的field改爲const修飾,因而忽然想了解一下resharper爲何這麼提示,因此整理以下:數組

 

咱們都知道,const和static readonly的確很像:經過類名而不是對象名進行訪問,在程序中只讀等等。在多數狀況下能夠混用。
兩者本質的區別在於,const的值是在編譯期間肯定的,所以只能在聲明時經過常量表達式指定其值。而static readonly是在運行時計算出其值的,因此還能夠經過靜態構造函數來賦值。
明白了這個本質區別,咱們就不難看出下面的語句中static readonly和const可否互換了:函數

複製代碼
1. static readonly MyClass myins = new MyClass();
2. static readonly MyClass myins = null;
3. static readonly A = B * 20;
   static readonly B = 10;
4. static readonly int [] constIntArray = new int[] {1, 2, 3};
5. void SomeFunction()
   {
      const int a = 10;
      ...
   }
複製代碼

1:不能夠換成const。new操做符是須要執行構造函數的,因此沒法在編譯期間肯定
2:能夠換成const。咱們也看到,Reference類型的常量(除了String)只能是Null。
3:能夠換成const。咱們能夠在編譯期間很明確的說,A等於200。
4:不能夠換成const。道理和1是同樣的,雖然看起來1,2,3的數組的確就是一個常量。
5:不能夠換成readonly,readonly只能用來修飾類的field,不能修飾局部變量,也不能修飾property等其餘類成員。post

 

所以,對於那些本質上應該是常量,可是卻沒法使用const來聲明的地方,可使用static readonly。 url

例如C#規範中給出的例子:spa

複製代碼
 1 public class Color
 2 {
 3     public static readonly Color Black = new Color(0, 0, 0);
 4     public static readonly Color White = new Color(255, 255, 255);
 5     public static readonly Color Red = new Color(255, 0, 0);
 6     public static readonly Color Green = new Color(0, 255, 0);
 7     public static readonly Color Blue = new Color(0, 0, 255);
 8 
 9     private byte red, green, blue;
10 
11     public Color(byte r, byte g, byte b)
12     {
13         red = r;
14         green = g;
15         blue = b;
16     }
17 }
複製代碼

 

static readonly須要注意的一個問題是,對於一個static readonly的Reference類型,只是被限定不能進行賦值(寫)操做而已。而對其成員的讀寫仍然是不受限制的。 
public static readonly MyClass myins = new MyClass();

myins.SomeProperty = 10;  //正常
myins = new MyClass();    //出錯,該對象是隻讀的code

可是,若是上例中的MyClass不是一個class而是一個struct,那麼後面的兩個語句就都會出錯。htm

 

 

Const 和 static readonly的區別:

      可能經過上述純概念性的講解,對有些初學者有些暈乎。下面就一些例子來講明下:     對象

複製代碼
 1 using System;
 2 class P
 3 {
 4     static readonly int A=B*10;
 5     static readonly int B=10;   
 6     public static void Main(string[] args)
 7     {
 8         Console.WriteLine("A is {0},B is {1} ",A,B);
 9     }
10 }
複製代碼

對於上述代碼,輸出結果是多少?不少人會認爲是A is 100,B is 10吧!其實,正確的輸出結果是A is 0,B is 10。blog

 

好吧,若是改爲下面的話:

複製代碼
using System;
 1 class P
 2 {
 3     const int A=B*10;
 4     const int B=10;   
 5     public static void Main(string[] args)
 6     {
 7         Console.WriteLine("A is {0},B is {1} ",A,B);
 8     }
 9 
10 }
複製代碼

對於上述代碼,輸出結果又是多少呢?難道是A is 0,B is 10?其實又錯了,此次正確的輸出結果是A is 100,B is那麼爲何是這樣的呢?其實在上面說了,const是靜態常量,因此在編譯的時候就將A與B的值肯定下來了(即B變量時10,而A=B*10=10*10=100),那麼Main函數中的輸出固然是A is 100,B is 10啦。而static readonly則是動態常量,變量的值在編譯期間不予以解析,因此開始都是默認值,像A與B都是int類型,故都是0。而在程序執行到A=B*10;因此A=0*10=0,程序接着執行到B=10這句時候,纔會真正的B的初值10賦給B。

相關文章
相關標籤/搜索