# C# coding style學習筆記 ## coding style目的 * 彼此好維護:確保一致性、易讀性 * 執行效能更好:了解執行成本 * 更安全:避免掉不安全的作法 ## C#三大特性 * 跨平台 * 強型別:在開發時使用型別的方式開發,好處是在編譯時期就能發現錯誤 * 物件導向:物件為類別的實體,為程式的基本單元,作抽象化、重複使用的動作,將功能區分開來,降低彼此的依賴程度 * 封裝:透過類別將資料封裝起來,達到重複使用,或是不需要被外部知道的資訊隱藏起來 * 繼承: * 多型: * P.S.非物件導向:中央集權,利用條件判斷function call function ## C#內置型別 使用C#內置型別,而非.net Class * 一致性: * short NOT System.Int16 * int NOT System.Int32 * long Not System.Int64 * string Not System.String ## 專案結構 方案>專案>組件>命名空間>CS檔>類別>類別成員 * 一個CS檔,只放一個類別(one cs file one class), 除了: * 巢狀類別:類別裡面還有一個類別 * POCO(允許):最原始的Class,單純的屬性、欄位,常見為資料型態,沒有其他方法或複雜的邏輯 * Partial(禁用):不會將同一個class分散在不同cs檔中,會找不到方法,程式內建可以,自己寫的不要 POCO經典範例,Restaurant>Food/Drink * 類別成員: * 欄位 int Field; 直接加存取修飾字(決定是否要給外面直接用),規定存取修飾詞一律開private * 屬性 int Property{get;set}(可以決定要不要給get、set,或只給其中一個),屬性才能公開使用 * 方法 * 常數 const int CONST=0 不能被更動的數 * 建構子 * 解構子 把物件從記憶體當中移除掉的時候,會自動呼叫解構子的方法,假如做遠端的連線 ,連線就需要幫他做回收的動作,就會在解構子裡面做一些切端連結的呼叫dispose,讓GC回收 * 巢狀類別: ## 存取修飾詞 * public * private * protected : 繼承的子類可以存取 * internal : 在同一個組件下都看的到 * protected internal : 類型或成員可以由其宣告之元件中的任何程式碼存取,或從另一個元件的衍生記憶體取 class * private protected : 類型或成員只能在其宣告元件中,透過相同 class 或衍生自該型別的程式碼來存取 class ## 檔案的屬性 組件名稱和命名空間(盡量一個)盡量一致,比較好找 * 輸出類型: * window應用程式: winform,有視窗 * 主控台應用程式: 沒有ui畫面(console) * 類別庫:專案編譯出來並不是一個應用程式dll組件 dll擴充 * 組件資訊: 規定build新的版本,部屬前一定要改組件版本 * 組件版本 * 檔案版本 ## magicNumber 看不出來變數是什麼意思,如何解決magicNumber? 看場合 * 給有意義的變數名稱 * 使用enum 列舉 * 常數 ## 重複的程式碼 什麼形況下會注意到自己使用重複的程式嗎? 做了Ctrl+C Ctrl+V * "警訊":方法做修改,哪邊要抽出來 * 維護會有困難(漏改): 一樣的Code複製三個地方,後面的人接手,但只看到一個地方 * 程式碼不易讀 ## 共用項目 * 共用常數 * 共通性的方法抽出來使用 ## 大括號的使用 * 一律單獨一行 * 判斷後一定要把執行的範圍用大括號刮起來 ```csharp= //錯誤,不易閱讀 if(dayOfWeek == DayOfWeek.Money)) BuyBreakfast(); // 在if裡面 GoToWork(); // 在if外面 ``` ## 變數宣告 一個變數宣告就佔一行,一致性 ```csharp= //使用 int a = 1; int b = 2; int c = 3; //不使用 int x = 1, y = 2, z = 3; ``` ## 命名規則 **所有命名都要使用有意義的命名,避免a、b、c、temp1、temp2等這類命名** * 常數 一律全大寫,以底線分隔單字 => VERSION_NUMBER * 區域變數、方法參數 小寫開頭,駝峰式命名 => computerGame * 類別成員(欄位、屬性、方法、巢狀類別、建構子......等等) 大寫開頭,駝峰式命名 => BasketballGame **方法** 使用動詞開頭 => GetData **類別與其他類別成員** 使用名詞開頭 **boolean** 必須含有判斷意義,用Is、Can、Has等詞開頭 **Interface** 命名一律以I開頭,泛型的型別參數一律使用<T> (base on .Net) ## 封箱裝箱 * 裝箱 : 值型別轉換為參考型別 * 拆箱 : 參考型別轉換為值型別 ``` java Integer i = 10; //裝箱 int n = i; //拆箱 ``` ## 空字串宣告 ```C# String a=String.Empty; ``` ## 使用///進行所有成員的XML註解 ```c# /// <summary> /// XML註解示範函式 /// </summary> /// <param name="index"></param> public void test(int index) { //示範函式 } ``` ## Double特殊值 * Double.PositiveInfinity 正無窮 * Double.NegativeInfinity 負無窮 * Double.NaN 非数 ## 隱含轉型 小轉大(安全轉換,不會遺失資料) e.g. int 轉 double ## 明確轉型 大轉小(**危險!** **有可能資料丟失,不安全轉換**) e.g. double 轉 int 衍生類別(子類別) 轉 基底型別(父類別) ## 代辦清單 ```C# //TODO(未實現) //UNDONE(未完成) //HACK(修改) ``` ## 交付原則 * 不能有警告,一個都不行 不要交出有錯誤、有警告的程式碼,讓別人替你debug,浪費大家的時間,交出有品質的code