程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則2:為你的常量選擇readonly而不是const(1)

Effective C#原則2:為你的常量選擇readonly而不是const(1)

編輯:關於C語言

對於常量,C#裡有兩個不同的版本:運行時常量和編譯時常量。

因為 他們有不同的表現行為,所以當你使用不當時,將會損傷程序性能或者出現錯誤 。

兩害相權取其輕,當我們不得不選擇一個的時候,我們寧可選擇一個 運行慢一點但正確的那一個,而不是運行快一點但有錯誤的那個。基於這個理由 ,你應該選擇運行時常量而不是編譯時常量(譯注:這裡隱藏的說明了編譯時常 量效率更高,但可能會有錯誤)。

編譯時常量更快更直接,但在可維護性 上遠不及運行時常量。保留編譯時常量是為了滿足那些對性能要求克刻,且隨著 程序運行時間的過去,其值永遠不發生改變的常量使用的(譯注:這說明編譯時 常量是可以不被C#采用的,但考慮到性能問題,還是做了保留)。

你可以 用關鍵字readonly來聲明(declare)一個運行時常量,編譯時常量是用關鍵字 const聲明的。

//Compile time constant:
public cocnst int _Millennium = 2000;
//Runtime constant:
public static readonly int _ThisYear = 2007;//

(譯注:原文為2004)

編譯時常量與運行時常量不同之處表現在如何對他們的訪問上。

一個編譯時常量會被目標代碼中的值直接取代。下面的代碼:

if (myDateTime.Year == _Millennium)

會與下面寫的代碼編譯成完 全相同的IL代碼:

if(myDateTime.Year == 2000)

運行時常量的值是在運行時確定的。當你引用一個只讀常量時(read-only)IL會 為你引用一個運行時常量的變量,而不是直接使用該值。

當你任意的使 用其中一個常量時,這些區別就在一些限制上表現出來。編譯時常量只能是基本 類型(primitive types)(built-in integral and floating-poing types),枚舉 或者是字符串。這些就是你只能給運行時常量在初始化時賦值的類型。這些基本 類就是可以被編譯器在編譯IL代碼時直接用真實的值所取代的數據類型。下面的 代碼塊(construct)不能通過編譯。你不能用new運算符初始化一個編譯時常量, 即使這個數據類型是值類型。

//Does not complIE, use readonly instead:

private const DateTime _classCreation = new DateTime (2000,1,1,0,0,0);

(譯注:DateTime是一個值類型數據,但上面的代碼 因為用了new運算符,編譯器無法在編譯確定具體的對象應該用什麼樣的實際值 來取代,所以無法通過編譯。)

編譯時常量僅限於數字和字符串。只讀變 量,也就是運行時常量,在構造函數(constructor)執行完成後它們是不以能被 修改的。但只讀變量是所有不同的,因為他們是在運行時才賦值的。當你使用運 行時常量時,你有更大的可伸縮性。有一點要注意的是,運行時常量可以是任何 類型的數據。而且你必須在構造函數裡對他們初始化,或者你可以用任何一個初 始化函數來完成。你可以添加一個DateTime結構的只讀變量(--運行時常量),但 你不能添加一個DateTime結構的(編譯時)常量。

你可以把每一個實例(的 常量)指定為只讀的,從而為每一個類的實例存放不同的值。與編譯時常量不同 的是,它只能是靜態的。

(譯注:簡單的講,運行時常量可以是一個類的 實例成員,也可以是一個類型的靜態成員,而編譯時常量只能是靜態成員,因此 類似:static const string m_name;的代碼是不能通過編譯的。)

只讀 數據最重要的區別是他們在運行時才確定值。當你使用只讀變量 時,IL會為你 產生一個對只讀變量引用,而不是直接產生數值。隨著時間的推移,這個區別在 (系統)維護上有深遠的潛在影響。

編譯時常量生成的IL代碼就跟直接使 用數值時生成的IL是一樣的,即使是在跨程序集時:一個程序集裡的編譯時常量 在另一個程序集會保留著同樣的值(譯注:這裡說的不是很清楚,看後面的這個 例子可能會更清楚一些)。

編譯時常量和運行時常量的賦值方法對運行時 的兼容性有所影響。

假設你已經在程序集Infrastructure中同時定義了 一個const和一個readonly變量:

public class UserfulValues {
public static readonly int StartValue = 5;
public const int EndValue = 10;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved