在c#中常量中修飾符使字段或局部變量保持不變。ReadOnly應用於c#中的字段,在初始化後值是常量。Static ReadOnly使ReadOnly字段具有類成員的特性。(可通過類名訪問)
請仔細閱讀關於常量和readonly之間的差異的總結,然後我將試着解釋後面的每一點。
常量與Readonly字段在c#中的10個主要區別
C#中的常量 | C#中Readonly |
---|---|
const關鍵字可以應用於字段或局部變量 | readonly關鍵字只應用於字段而不是局部變量 |
我們必須在公開的時候分配常量字段 | 我們可以在聲明或構造函數時指定readonly字段,而不是在任何其他方法中。 |
沒有分配內存,因爲在編譯後,在IL代碼中嵌入了常量值 | 爲Readonly字段分配的動態內存,可以在我們運行時獲得值。 |
常量在c#中是默認靜態的。只能通過類名訪問 | Readonly屬於需要過類實例訪問的對象。要使它成爲類成員,我們需要在readonly之前添加static關鍵字。 |
我們可以聲明如下所構建的(基本類型)數據類型爲常量 Boolean,Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal和string. | 一樣不變 |
值是常量(因爲它屬於類) | 根據使用的構造函數(因爲它屬於類的對象),其值可能會有所不同 |
如果我們想要對某些類(非原始類型)聲明常量,我們應該將其賦值爲null,但是這是沒有用的。 | 如果聲明一個非基本類型(引用類型),readonly只有引用是不可變的,而不是它包含的對象。(見下面的例子) |
不要使用可能導致dll版本問題時發生變化的const字段(參見示例) | 當在運行時獲得的值時,沒有dll版本控制問題 Static ReadOnly字段的Const字段不能作爲ref或out參數傳遞 |
C#中的常量字段或局部變量:
在C#中我們將使用關鍵字 "const" 聲明常量字段或局部變量.
當你定義一個常量字段時,它的值必須在聲明本身的時候被分配,之後我們不能改變它的值。通過下面的例子來了解它
Public class Program { const int fieldConstant = 10; //字段 static void Main(string[] args) { const int X = 10, Y = 50; //正確的 //局部變量 const int Z = X + Y; //正確的 const int A = X + GettheValue(); // 錯誤的 } public static int GettheValue() { const int localx=10; return 10; } }
前兩行沒有任何錯誤,因爲X、Y、Z字段值是在編譯時本身進行計算的。但是在第三行中,我們聲明瞭一個變量“A”作爲常量,並嘗試使用GettheValue()方法在運行時返回值。由於必須在編譯時分配常量變量,因此該行不會執行。
c#中的 字段 是在類或結構中直接聲明的變量
在上面的示例中 fieldConstant 是一個字段,因爲它在程序類中直接聲明。
我們可以將局部變量聲明爲 const ,如上面所示的GetTheValue()方法。
以下構建的值類型可以聲明爲常量:int, long, char, float, double, decimal, bool, byte, short,string變量也可作爲常量
我們可以將非基原類型賦給null來定義一個常量。但是,將一個常量引用類型聲明爲null是沒有用的。
const string constantString = "Hi Iam Constant"; //正確的 const Program program = new Program(); //錯誤的 const Program program1 = null; //正確的
我們不能將一個常量變量聲明爲靜態變量,因爲默認情況下,常量被視爲靜態成員。
ReadonlyConstant r1=new ReadonlyConstant();// 請參閱下面的類聲明代碼 Console.WriteLine(r1.ynumber); //錯誤的 Console.WriteLine(ReadonlyConstant.ynumber);//正確的
作爲默認靜態的常量變量,我們無法從類的實例中訪問它。所以我們不能將const值作爲ref或out參數傳遞。
C#中的ReadOnly字段:
在C#中我們可以將字段聲明爲ReadOnly而不是局部變量。
ReadOnly字段可以在聲明的時候進行初始化,或者只能在對象創建時只調用一次的構造函數中進行初始化,而不是在任何其他方法中。
public class ReadonlyConstant { public const int numberOfDays = 7; //字段 public readonly double PI=3.14; //內聯初始化 public readonly int znumber; public readonly List<int> readonlyList; public ReadonlyConstant() { znumber= 50;//構造函數初始化 } public ReadonlyConstant(int x) { znumber=100; } public NormalMethod() { //readonly int i=0; 這是錯誤的 } }
根據使用的構造函數,值可能會有所不同。即,readonly字段屬於類的對象。
現在我們將討論常量和readonly字段之間的區別,正如在第二個點中提到的,常量字段沒有分配內存,而值直接嵌入IL代碼中。請參閱下面的IL代碼圖片。
我使用resharper工具查看了上面的示例程序(ReadonlyConstant.cs)的中間語言(IL)代碼。
正如您可以看到的IL代碼的const字段numberOfdays的值(7)直接嵌入IL代碼。其中,readonly字段piValue顯示爲piValue。該值可在運行時獲得。
這就導致了版本控制問題。
【本文由“程序員哥哥”發佈,2017年10月14日】