不定時更新翻譯系列,此系列更新毫無時間規律,文筆菜翻譯菜求各位看官老爺們輕噴,如覺得我翻譯有問題請挪步原博客地址
在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。該值可在運行時獲得。
這就導致了版本控制問題。
C#中常量字段的版本控制:
我將上面的示例程序編譯為類庫(A),並在另一個項目(B)中使用它作為參考。現在看一下生成的項目B的IL代碼
在項目B的代碼中,在IL代碼中嵌入的常量字段數的值。現在的問題是,在源中(A類庫的ReadonlyConstant.cs),常量字段 (numberOfdays )值改為5,並編譯並生成一個新的dll
但是,除非我們編譯這個項目,否則這個常量字段的新值不會影響B項目。編譯后,新的常量字段值將嵌入到項目B的IL代碼中。
為了解決這個問題,我們將使用static readonly字段。
C#中的static readonly
由於readonly字段值不同,取決於使用的構造函數。為了使它成為類成員(靜態成員)和唯一的類,我們將在變量之前添加static關鍵字,如下所示。
public class ReadonlyStatic
{
public static readonly string x = "Hi";
public static readonly string y;
public ReadonlyStatic()
{
//y = "Hello"; 這是錯誤的
}
static ReadonlyStatic()
{
y = "Hello";
}
}
現在我們可以把它作為常量使用,在整個類中,我們將解決dll版本的常量變量問題。可能存在一些性能問題,但不需要構建目標項目,因為值可以在運行時獲得。
如上面的示例所示,我們僅在聲明或靜態構造函數時分配static readonly字段。
C#中Readonly和Static Readonly:
以下是C#中readonly和static readonly字段之間的主要區別。
C#中的Readonly | C#中的Static Readonly |
---|---|
可以在聲明或構造函數的時候分配 | 在聲明或靜態構造函數時可以分配 |
根據使用的構造函數,值可能會不同 | 初始化后值將是常量 |
在C#中何時使用常量和readonly
當值是絕對不變的時候,使用常量,這在時間上是不變的。例如一周的天數是7。這始終是常數。而在使用static readonly時,要避免dll版本問題。
由於在IL內嵌有不變的值,我們可以使用常量修飾符來獲得性能上的好處。
如果我們想要對類(或對象)的不同實例使用不同的常量值,請使用readonly。
歡迎轉載,轉載請注明翻譯原文出處(本文章),原文出處(原博客地址),然后謝謝觀看
如果覺得我的翻譯對您有幫助,請點擊推薦支持:)