国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[CLR via C#]7. 常量和字段

2019-11-17 03:22:47
字體:
來源:轉載
供稿:網友

[CLR via C#]7. 常量和字段

7.1常量

  常量(constant)是一個特殊的值,它是一個從不變化的值。

  在定義常量時,它的值必須在編譯時確定。確定之后,編譯器將常量的值保存到程序集的元數據中。這就意味著只能為編譯器認定的基元類型定義常量。  C#是允許定義一個非基元類型的常量變量(constant variable),但這個值應設為null。
public sealed class SomeType {    //SomeType不是基元類型,但C#允許定義    //值為null的這種類型的一個常量變量    public const SomeType Empty = null;    }

  由于常量的值從不變化,所以常量總是被視為類型定義的一部分。所以,常量是靜態成員,而不是實例成員。定義常量將導致創建元數據。

  代碼引用一個常量符號時,編譯器會在定義常量的程序集的元數據中查找該符號,提取常量的值,并將值嵌入生成的IL代碼中。由于常量的值直接嵌入代碼中,所以運行時不需要為常量額外分配內存。  除此之外,不能獲取常量的地址,也不能以傳遞引用的方式傳遞常量。  基于上一條,假如A程序集只依賴于B程序集中的常量,那么編譯后,即使刪除B程序集,A程序集也不會受到影響,也是能找到B程序集中定義的常量值。7.2字段  字段(field)是一種數據成員,其中容納了一個值類型的實例或者對一個引用類型的引用。  下表總結了應用于字段的修飾符:
CLR術語C#術語說明
Staticstatic這種字段是類型狀態的一部分,而不是對象狀態的一部分
Instance默認這種字段與類型的一個實例關聯,而不是與類型本身關聯
InitOnlyreadOnly這種字段只能由一個構造器方法中的代碼寫入
Volatilevolatile看到訪問這種字段的代碼,編譯器、CLR或硬件就不會執行一些"線程不安全"的優化措施
    CLR支持類型(靜態)字段和實例(非靜態)字段。對于類型字段,用于容納字段數據的動態內存是在類型對象中分配的,而類型對象是在類型加載到一個AppDomain時創建的。什么時候要將類型加載到一個AppDimain中呢?通常是在引用了該類型的任何方法首次進行JIT編譯的時候。  對于實例字段,用于容納字段數據的動態內存則是在構造類型的一個實例時分配的。  由于字段存儲在動態內存中,所有它們的值在運行時才能獲取。字段還解決了常量存在的版本控制的問題。此外,字段可以是任何數據類型。  CLR支持readonly字段和read/write字段。大多數字段是read/write字段,這意味著在代碼執行過程中,字段可以多次改變。但是,readonly字段只能在一個構造器方法中寫入(在這有人會有疑問,我可以直接定義readonly的值啊?比如PRivate readonly int ss = 123;不必從構造器方法中寫入?這問題,以后會提到)。注意,可以利用反射來修改readonly字段。  下面演示了如何定義一個與類型本身關聯的readonly靜態字段和讀/寫靜態字段。另外還定義了read/wite靜態字段,以及readonly和read/write實例字段。
public sealed class SomeType {    // 這是一個靜態readonly字段:在運行時對Random類進行初始化    // 它的值會被計算并存儲到內存中    public static readonly Random s_random = new Random();     // 這是一個靜態read/write字段    private static Int32 s_numberOfWrites = 0;     // 這是一個實例readonly字段    public readonly String Pathname = "Untitled";     // 這是一個實例read/write字段    private System.IO.FileStream m_fs;     public SomeType(String pathname) {        // 這行修改只讀字段Pathname        // 由于是在構造其中,所有可以進行修改        this.Pathname = pathname;    }     public String DoSomething() {        // 該行讀寫靜態read/write字段        s_numberOfWrites = s_numberOfWrites + 1;         // 這行讀取readonly實例字段        return Pathname;    }}

  在上述代碼中,許多字段都是內聯初始化的。C#允許使用內聯初始化語法來初始化類的常量、read/write字段和readonly字段。在后面會講到,C#實際是在構造器中對字段進行初始化的,字段的內聯初始化只是一種語法上的簡化而已。另外,在C#中使用內聯初始化,有一些性能問題需要考慮,這些以后會著重講解。

  注意,當某個字段是引用類型,并且該字段標記為readonly時,那么不可改變的引用,而非字段引用的值。
internal static class ReadOnlyReferences {   public sealed class AType {      // InvalidChars總是引用同一個數組對象      public static readonly Char[] InvalidChars = new Char[] { 'A', 'B', 'C' };   }    public sealed class AnotherType {      public static void M() {         // 下面三行代碼是合法的,可通過編譯并運行         // 修改InvalidChars數組中的字符         AType.InvalidChars[0] = 'X';         AType.InvalidChars[1] = 'Y';         AType.InvalidChars[2] = 'Z';          // 下一行代碼是非法的,無法通過編譯         // 因為不能讓InvalidChars 引用別的什么東西         //AType.InvalidChars = new Char[] { 'X', 'Y', 'Z' };      }   }}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 云龙县| 洛阳市| 体育| 西城区| 仪陇县| 东阳市| 澜沧| 葫芦岛市| 斗六市| 易门县| 盱眙县| 容城县| 平泉县| 墨玉县| 永靖县| 沙洋县| 崇义县| 大港区| 加查县| 亳州市| 化州市| 辽阳县| 馆陶县| 德阳市| 梨树县| 日照市| 怀来县| 溧阳市| 中方县| 阆中市| 丰顺县| 新宁县| 康定县| 吉木萨尔县| 靖江市| 乌鲁木齐市| 阜康市| 广平县| 克山县| 商丘市| 遵义市|