C#中的readonly和const兩個關鍵字都可以用來定義系統變量,那兩者之間有什麼差別呢?
1. const變量指派後,就不可以對其進行修改。且在定義時就需要給它指派,使用const修飾的變量是static的。可以使用YourClass.ConstantName的方式進行通路;
2. readonly變量可以在定義時指派,也可以在構造方法中指派或者修改定義時賦給的初始值;
另外還有一個細微的差别。看下面的場景,我在AssemblyA中定義了一個類如下:
public class Readonly_VS_Const
{
public const int I_Const_Value = 100;
public readonly int I_Readonly_Value = 20;
public Readonly_VS_Const()
{
I_Readonly_Value = 55;
}
}
在AssemblyB中引用了AssemblyA,并且使用了這些常量,
static void Main(string[] args)
{
int constValue = Readonly_VS_Const.I_Const_Value;
Readonly_VS_Const vs = new Readonly_VS_Const();
int readonlyValue = vs.I_Readonly_Value;
Console.WriteLine("Const Value:{0}--Readonly Value:{1}",
constValue, readonlyValue);
Console.ReadKey();
}
檢視一下IL代碼,
注意檢視使用黃色和綠色框标記的兩行代碼。
假設AssemblyA和AssemblyB編譯完成後均放在AssemblyB的目錄下
1. const變量類似與一種替換的方式,直接将定義的100寫入到IL代碼中。當我修改了I_Const_Value的值為200後,AssemblyB需要在程式重新編譯後才能獲得更新後的數值;
2. readonly的變量值,很像ref類型,readonly值不會直接寫入到AssemblyB的IL代碼中,這就意味者如果AssemblyA中readonly的值被修改後,你隻需要重新編譯一下AssemblyA即可。AssemblyB在調用時會找到根據變量的記憶體位置讀取修改後的值。
static readonly vs const,
onst和static readonly的确很像:通過類名而不是對象名進行通路,在程式中隻讀等等。在多數情況下可以混用。
二者本質的差別在于,const的值是在編譯期間确定的,是以隻能在聲明時通過常量表達式指定其值。而static readonly是在運作時計算出其值的,是以還可以通過靜态構造函數來指派。
請看下面的例子:
class Program
{
static readonly int A = B * 10;
static readonly int B = 10;
static void Main(string[] args)
{
Console.WriteLine("A: {0} B: {1}", A, B);
}
}
結果如下:
将static readonly修改為const,
class Program
{
const int A = B * 10;
const int B = 10;
static void Main(string[] args)
{
Console.WriteLine("A: {0} B: {1}", A, B);
}
}
結果如下:
那麼為什麼是這樣的呢?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。
感謝您的閱讀!