# [C#] `const` vs `readonly` ###### tags: `C#` `Programming` ## `const` - **編譯時期**常數 - 只能用於primitive type或refernce type - 只能在宣告時賦值 - 在class內,被視為靜態成員(static member) ## `readonly` - **執行時期**常數 - 只能在宣告時賦值或利用建構子(Contructor) - 與`const`比較,`readonly`修飾完依然是一般成員(member variable) ## 實驗 ==使用VS2019== ### 第一步 - 新增專案 1. 新增一個ConsoleApp(圖1) ![](https://i.imgur.com/r68qvBy.png) 2. 對該專案的Solution新增一個Library,中文會叫做「程式庫」(圖2) ![](https://i.imgur.com/UeC4VwU.png) ![](https://i.imgur.com/oFkKx8M.png) 3. 新增對程式庫的相依性(新增Reference) (圖3) ![](https://i.imgur.com/PRGAbsY.png) ### 第二步 - 建置 Lib ```csharp= namespace ExampleLib { public class Constant { public static readonly string ReadOnlyString = "Readonly 1"; public const string ConstString = "Const 1"; } } ``` ConsoleApp ```csharp= using System; using ExampleLib; namespace Example { class Program { static void Main(string[] args) { Console.WriteLine($"{Constant.ReadOnlyString}"); Console.WriteLine($"{Constant.ConstString}"); Console.ReadKey(); } } } ``` 建置輸出後,沒意外會出現 ```tiddlywiki= Readonly 1 Const 1 ``` ### 第三步 - 更新 #### 檔案總管 把ConsoleApp的檔案總管打開後,會看到 (圖4): ![](https://i.imgur.com/yp9ZnbQ.png) 兩個主要的檔案,一個是執行檔(.exe),另一個程式庫(.dll) 再來更新我們**程式庫(DLL)** ```csharp= namespace ExampleLib { public class Constant { public static readonly string ReadOnlyString = "Readonly 2"; public const string ConstString = "Const 2"; } } ``` :::warning :warning: 記得只要更新程式庫,不要直接按`F5`全部都建置了 ::: 然後回到ConsoleApp的資料夾,把程式庫建置出來的元件全部複製一份,複製到ConsoleApp的資料夾裡。 之後再次打開執行檔,會發現`readonly`跟著程式庫更新了,但`const`沒有 ```tiddlywiki= Readonly 2 Const 1 ``` 這就是上面所說的**編譯時期常數**和**執行時期常數** ## 結論 - 建議使用執行期常數(static readonly),而非編譯期常數(const)。 ## 參考資料 - [const vs readonly](https://dotblogs.com.tw/bda605/2019/06/30/223857) - [C# - const vs static readonly](https://blog.johnwu.cc/article/c-sharp-const-vs-static-readonly.html) - [const 和 readonly 特性與使用時機](https://ronsun.github.io/content/20180519-const-vs-readonly.html)