之前只是知道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
好吧,若是改爲下面的話:
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。