1.常量
常量是乙個特殊的符號,它有乙個不改變的值,定義常量時,它的值必須在編譯時確定,確定後編譯器將常量的值儲存到程式集的元資料中。常量總是被視為靜態成員,而不是例項成員,定義常量將導致建立元資料。
這意味著只能為編譯器確定的基元型別定義常量。然後c#也允許定義乙個非基元型別的常量變數,前提是把它的值設為null。
class program
public static const program p=null;
public static const program p=new program();//編譯出錯,只能用null對引用型別(字串除外)的常量字段進行初始化
**引用乙個常量符號時,編譯器會在定義常量的程式集的元資料中查詢該符號,然後提取常量的值並將值嵌入生成的il**中,由於常量的值直接嵌入**,所以執行時不會為常量分配任何記憶體,因此,不能獲取常量的位址,也不能以傳址的方式傳遞常量。
所以說常量沒有很好的跨程式集版本控制特性,只有在確定乙個符號的值從不變化時,才使用常量。
如果希望在執行時從乙個程式集中提取另乙個程式集中的值,那麼不應該使用常量,而應該使用readonly欄位。
2.欄位
欄位是一種資料成員,容納了乙個值型別的例項,或者對乙個引用型別的引用。
clr支援型別欄位和例項字段,對於型別字段,用於容納字段資料的動態記憶體是在型別物件中分配的。而型別物件是在型別載入到乙個appdomain時建立的,什麼時候載入到appdomain呢?這通常是在引用了該型別的任何方法首次進行jit編譯時。對於例項字段,用於容納字段資料的動態記憶體則是在構造型別的乙個例項時分配的。
clr支援readonly欄位和read/write欄位,大多數欄位都是read/write的,**執行中字段的值可以多次改變,但是readonly欄位只能在乙個構造器方法中寫入。
internal class manager
public readonly int d=200;
public manager(int r)
//修改字讀字段d,因為**在構造器中,所以允許這樣做。
this.d = r;
class program
public const program p=null;
static void main()
manager m = new manager(400);
console.writeline(m.d);//
當某個欄位時引用型別時,並且該欄位標記為readonly,那麼不可改變的是引用,而不是字段引用的物件:
internal class manager
public static readonly int n =new int;
public readonly int d=200;
public manager(int r)
this.d = r;
class program
public const program p=null;
static void main()
manager.n[0] = 400;
manager.n[1] = 800;
foreach (int p in manager.n)
console.writeline(p);
}//輸出400,800,44,55,66
許多欄位都是內聯初始化的(直接在**中賦值來初始化,而不是通過構造器。)c#允許使用這種方便的內聯初始化語法來初始化類的常量,字段。但是c#實際是在構造器中對字段進行初始化的,欄位的內聯初始化只不過是語法上的簡化而已。在c#中初始化乙個欄位時,如果使用內聯語法,而不是在構造器中賦值,有一些效能問題需要考慮
作者 小小白白
C 中的常量和字段
1.常量 常量是乙個特殊的符號,它有乙個不改變的值,定義常量時,它的值必須在編譯時確定,確定後編譯器將常量的值儲存到程式集的元資料中。常量總是被視為靜態成員,而不是例項成員,定義常量將導致建立元資料。這意味著只能為編譯器確定的基元型別定義常量。然後c 也允許定義乙個非基元型別的常量變數,前提是把它的...
C 中的字段,屬性,常量
一種表示與物件或型別 類或結構體 關聯的變數,舊稱成員變數 attributes field modifiers type variable declarators 字元宣告,括號表示可選字段修飾符field modifier關於internal 字段初始值 隱式初始化,字段獲得該型別預設值 一種用...
常量和字段
定義常量符號時,它的值必須能在編譯時確定。確定之後,編譯器將常量的值儲存到程式集的元資料中。這意味著只能為編譯器認定的基元型別定義常量。在c 中,以下型別都是基元型別,可以定義常量 boolean char byte sbyte int16 uint16 int32 uint32 int64 uin...