C#引入了readonly修飾符來表示只讀域,const來表示不變常量。顧名思義對只讀域不能進行寫操作,不變常量不能被修改,這兩者到底有什 麼區別呢?只讀域只能在初始化--聲明初始化或構造器初始化--的過程中賦值,其他地方不能進行對只讀域的賦值操作,否則編譯器會報錯。只讀域可以是實例 域也可以是靜態域。只讀域的類型可以是C#語言的任何類型。但const修飾的常量必須在聲明的同時賦值,而且要求編譯器能夠在編譯時期計算出這個確定的 值。const修飾的常量為靜態變量,不能夠為對象所獲取。const修飾的值的類型也有限制,它只能為下列類型之一(或能夠轉換為下列類型的): sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum類型, 或引用類型。值得注意的是這裡的引用類型,由於除去string類型外,所有的類型出去null值以外在編譯時期都不能由編譯器計算出他們的確切的值,所 以我們能夠聲明為const的引用類型只能為string或值為null的其他引用類型。顯然當我們聲明一個null的常量時,我們已經失去了聲明的意義 --這也可以說是C#設計的尴尬之處!
這就是說,當我們需要一個const的常量時,但它的類型又限制了它不能在編譯時期被計算出確定的值來,我們可采取將之聲明為static readonly來解決。但兩者之間還是有一點細微的差別的。看下面的兩個不同的文件:
//file1.cs
//csc /t:library file1.cs
using System;
namespace MyNamespace1
{
public class MyClass1
{
public static readonly int myFIEld = 10;
}
}
//file2.cs
//csc /r:file1.dll file2.cs
using System;
namespace MyNamespace2
{
public class MyClass1
{
public static void Main()
{
Console.WriteLine(MyNamespace1.MyClass1.myFIEld);
}
}
}
我們的兩個類分屬於兩個文件file1.cs 和file2.cs,並分開編譯。在文件file1.cs內的域myField聲明為static readonly時,如果我們由於某種需要改變了myField的值為20,我們只需重新編譯文件file1.cs為file1.dll,在執行 file2.exe時我們會得到20。但如果我們將static readonly改變為const後,再改變myField的初始化值時,我們必須重新編譯所有引用到file1.dll的文件,否則我們引用的 MyNamespace1.MyClass1.myFIEld將不會如我們所願而改變。這在大的系統開發過程中尤其需要注意。實際上,如果我們能夠理解 const修飾的常量是在編譯時便被計算出確定的值,並代換到引用該常量的每一個地方,而readonly時在運行時才確定的量--只是在初始化後我們不 希望它的值再改變,我們便能理解C#設計者們的良苦用心,我們才能徹底把握const和readonly的行為!
---------------------
Features:
Examples:
Explaintion:
- 如果結合數據庫使用,ID fIEld通常都會都會與某個表的主健(primary key)關聯起來,如Orders表的OrderID。
- 數據庫的主健通常采用以下三種方式:
- 自動遞增值。你可以通過把DataColumn.AutoIncrement設定為true值來激活自動遞增特性。
- 唯一名稱。這個是使用自己定義的算法來生成一個唯一序列號。
- GUID(全局唯一標識符)。你可以通過System.Guid結構來生成GUID,如上例。
using System;
enum CustomerKind
{
SuperVip,
Vip,
Normal
}
class Customer
{
public Customer(string name, CustomerKind kind)
{
m_Name = name;
m_Kind = kind;
}
private string m_Name;
public string Name
{
get { return m_Name; }
}
private CustomerKind m_Kind;
public CustomerKind Kind
{
get { return m_Kind; }
}
public override string ToString()
{
return "Name: " + m_Name + "[" + m_Kind.ToString() + "]";
}
}
Comments:
------------------------------------------------
我們都知道,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等其他類成員。
因此,對於那些本質上應該是常量,但是卻無法使用const來聲明的地方,可以使用static readonly。例如C#規范中給出的例子:
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);static readonly需要注意的一個問題是,對於一個static readonly的Reference類型,只是被限定不能進行賦值(寫)操作而已。而對其成員的讀寫仍然是不受限制的。
public static readonly MyClass myins = new MyClass();
…
myins.SomeProperty = 10; //正常
myins = new MyClass(); //出錯,該對象是只讀的
但是,如果上例中的MyClass不是一個class而是一個struct,那麼後面的兩個語句就都會出錯。
private byte red, green, blue;
public Color(byte r, byte g, byte b)
{
red = r;
green = g;
blue = b;
}
}
using System;
namespace ConstantLab
{
class Program
{
static void Main(string[] args)
{
Constant c = new Constant(3);
Console.WriteLine("ConstInt = " + Constant.ConstInt.ToString());
Console.WriteLine("ReadonlyInt = " + c.ReadonlyInt.ToString());
Console.WriteLine("InstantReadonlyInt = " + c.InstantReadonlyInt.ToString());
Console.WriteLine("StaticReadonlyInt = " + Constant.StaticReadonlyInt.ToString());
Console.WriteLine("Press any key to ;continue");
Console.ReadLine();
}
}
class Constant
{
public Constant(int instantReadonlyInt)
{
InstantReadonlyInt = instantReadonlyInt;
}
public const int ConstInt = 0;
public readonly int ReadonlyInt = 1;
public readonly int InstantReadonlyInt;
public static readonly int StaticReadonlyInt = 4;
}
}
const和readonly的區別 這同樣是一個面試的基礎題。可以看看學習下哦
readonly關鍵字與 const 關鍵字的區別:
1、const 字段只能在該字段的聲明中初始化。readonly 字段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 字段可能具有不同的值。
2、const 字段是編譯時常數,而 readonly 字段可用於運行時常數,如下例所示: public static readonly uint l1 = (uint) DateTime.Now.Ticks;
歸納下:不同處就在於字段的初始化的方式不同。具體的體現方式就是上述兩點。另外什麼叫編譯時常數,什麼是運行是常數,各位應該也有一個印象了吧。