常量:
常量是值從不變化的符號,它的值必須能在編譯時(shí)就確定菜职,確定以后編譯器將其值保存到程序集元數(shù)據(jù)中敷矫。
常量總是被視為靜態(tài)成員灸叼。
代碼引用時(shí),會在元數(shù)據(jù)中查找常量符號数尿,提取其對應(yīng)的值仑性,然后將值嵌入到生成的IL代碼中。(這樣在運(yùn)行時(shí)就不需要為其分配內(nèi)存)
只有在確定了一個(gè)符號的值從不變化以后右蹦,才應(yīng)該定義一個(gè)常量诊杆。
如果希望在運(yùn)行時(shí)從一個(gè)程序集中提取另一個(gè)程序集中的值,就不應(yīng)該使用常量何陆,而應(yīng)該使用readonly字段晨汹。
字段:
- 字段是一種數(shù)據(jù)成員,其中內(nèi)容可分為以下兩種:
- 一個(gè)值類型的實(shí)例贷盲。
- 對一個(gè)引用類型的引用淘这。
- 字段大致分為以下兩種:
- 類型字段:其容納數(shù)據(jù)所需的動態(tài)內(nèi)存是在類型對象中分配的。
- 實(shí)例字段:其容納數(shù)據(jù)所需的動態(tài)內(nèi)存是在構(gòu)造類型的實(shí)例時(shí)分配的。
- 字段可用的修飾符:
- static :表明修飾的字段是類型狀態(tài)的一部分铝穷,而不是對象狀態(tài)的一部分朦乏。
-
readonly :表明修飾的字段只能由一個(gè)構(gòu)造器方法中的代碼寫入。(構(gòu)造器方法只能調(diào)用一次氧骤,即對象首次創(chuàng)建時(shí)(實(shí)例字段)或是對類進(jìn)行初始化時(shí)(類型字段))
(注:除了構(gòu)造器呻疹,還可以利用反射來修改readonly字段。)
相對應(yīng)的代碼演示:
public sealed class SomeType
{
//這是一個(gè)靜態(tài) readonly 字段筹陵;在運(yùn)行時(shí)對這個(gè)類進(jìn)行初始化時(shí)刽锤,它的值會被計(jì)算并存儲到內(nèi)存中。
public static readonly Random s_random = new Random();
//這是一個(gè)靜態(tài) read/write 字段
private static Int32 s_numberOfWrites = 0;
//這是一個(gè)實(shí)例 readonly 字段
private System.IO.FileStream m_fs;
public SomeType(String pathname)
{
//改行修改只讀字段(readonly修飾的)pathname朦佩,在構(gòu)造器中可以這么做并思。
this.Pathname = pathname;
}
public String DoSomething()
{
//該行讀寫靜態(tài) read/write 字段
s_numberOfWrites = s_numberOfWrites + 1;
//該行讀取 readonly 實(shí)例字段
return Pathname;
}
}
(在上述代碼中,存在如:private static Int32 s_numberOfWrites = 0; 這種直接在類型定義中(構(gòu)造器方法外)為常量和字段進(jìn)行初始化的操作语稠,被稱為內(nèi)聯(lián)初始化宋彼。)
內(nèi)聯(lián)初始化:指在代碼中直接賦值來初始化,而不是將對構(gòu)造器的調(diào)用寫出來仙畦。
(其實(shí)質(zhì)還是在構(gòu)造器中進(jìn)行初始化输涕,只是一種形式上的簡便化語法,是C#語言提供的 語法糖)
readonly字段如果是引用類型慨畸,不可改變的是引用莱坎,而非字段引用的對象。(類似于C++中的const指針)其演示代碼如下:
public sealed class AType
{
//InvalidChars 總是引用同一個(gè)數(shù)組對象
public static readonly Char[] InvalidChars = new Char[] {'A','B','C'};
}
public sealed class AnotherType
{
public static void M()
{
//下面三行代碼是合法的寸士,可通過編譯檐什,并可成功修改 InvalidChars 數(shù)組中的字符
AType.InvalidChars[0] = 'X';
AType.InvalidChars[1] = 'Y';
AType.InvalidChars[2] = 'Z';
//下一行代碼是非法的,無法通過編譯的弱卡,因?yàn)椴荒茏?InvalidChars 引用別的什么東西乃正。
AType.InvalidChars = new Char[] {'X','Y','Z'};
}
}