C#擁有兩種不同的常量:靜態常量(compile-time?constants)和動態常量(runtime??constants)。它們有不同的特性,錯誤的使用不僅會損失效率,還可能造成錯誤。相比之下,靜態常量在速度上會稍稍快一些,但是靈活性卻比動態常量差很多。?
//靜態常量(隱式是靜態的)
public?const?int??compiletimeConstant?=?1;
//動態常量
public?static?readonly?runtimeConstant?=??1;
?????靜態常量在編譯時會將其替換為所對應的值,也就是說下面這2句話通過編譯器編譯后產生的IL是一樣的。
//通過編譯后二者會被翻譯成相同的中間語言
int?myNum?=??compiletimeConstant;
int?myNum?=?1;
?????動態常量的值是在運行時獲得的。IL中將其標為只讀常量,而不是用常量的值代替。
?????靜態常量只能被聲明為簡單的數據類型(內建的int和浮點型)、枚舉或字符串。下面的程序段是通不過編譯的。你不能用new關鍵字初始化一個靜態常量,即便是對一個值類型來說。
//這樣是錯誤的
public?const?DateTime?myDateTime?=?new??DateTime(2006,9,1,0,0,0);
//這樣是可以的
public?static?readonly?DateTime??myDateTime?=?new?DateTime(2006,9,1,0,0,0);
???????只讀數據也是常量的一種,它們不能在構造器初始化之后被修改。但是它同靜態常量不同,它的值是在運行時才被指派的,因此就會獲得更大的靈活性。動態常量可以是任意的數據類型。
???????二者最大的差別在于:靜態常量在編譯時會將其換為對應的值,這就意味著對于不同的程序集來說,當你改變靜態常量的時候需要將其重新編譯,否則常量的值不會發生變化,可能引發潛在的問題,而動態常量就不會有這種情況。
?????用const定義的常量(隱式是靜態的),需要像訪問靜態成員那樣去訪問const定義的常量,而用對象的成員方式去訪問會出編譯錯誤。?聲明的同時要設置常量值。
??????從另一方面來說,如果你的確要聲明一些從不改變且處處唯一的常量,例如鉤子函數SetWindowsHookEx的idHook參數或序列化時的版本等,就應該使用靜態常量。但是用到這樣的常量的機會不多。一般來說我們應該使用靈活性更高的動態常量。
??????????????靜態常量???????????動態常量
?
內存消耗????????無??????????????????因為要保存常量?有消耗
?
初始化?????????很少的簡單類型,?????任意類型,可以在類構造函數中賦值
???????????????不能new,必須在
????????????????聲明同時賦值
?
何時發揮作用??編譯時進行替換??????相當于類中的數據成員
轉載于:https://www.cnblogs.com/zhangchengye/p/5155578.html