---
# System prepended metadata

title: C# coding style學習筆記

---

# 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

