《.NET 設計規範》第 5 章:成員設計

來源:互聯網
上載者:User

標籤:初始化   組元   枚舉   通用   安全   cep   支援   最佳化   簡單   

《.NET 設計規範》第 5 章:成員設計5.1 成員設計的通用規範

  要盡量用描述性的參數名來說明在較短的重載中使用的預設值。

  避免在重載中隨意地改變參數的名字。如果兩個重載中的某個參數表示相同的輸入,那麼該參數的名字應該相同。

  避免使重載成員的參數順序不一致。在所有的重載中,同名參數應該出現在相同的位置。

  要把最長的重載成員定義成重載成員中唯一的虛成員。

  不要用 ref 或 out 修飾符來對成員進行重載。

  不要定義這樣的重載:位於同一個位置的參數有相似的類型但卻有不同的語義。

  要允許在傳遞參數時將選擇性參數設為 null。

  要優先使用成員重載,而不是定義有預設參數的成員。

  顯式地實現介面成員。

  避免顯示地實現介面成員 - 如果沒有很強的理由。

  考慮顯式地實現介面成員 - 如果希望介面成員只能通過該介面來調用。

  考慮通過顯式地實現介面成員的方式來類比變體。

  考慮在需要隱藏一個成員並增加另一個名字更合適的等價成員時,顯式地實現介面成員。

  不要把介面成員的顯示實現當做安全壁壘。

  要為顯式實現的介面成員提供具有相同功能的受保護的虛成員 - 如果希望讓衍生類別對該功能進行定製。

  考慮使用屬性 - 如果該成員表示類型的一種邏輯屬性。

  要使用屬性而不要使用方法 - 如果屬性的值儲存在進程記憶體中,而且提供屬性的目的僅僅是為了訪問該值。

  要在下列情況中時使用方法而不要使用屬性:

    該操作比欄位訪問要慢幾個數量級;

    該操作是一個轉換操作,如:object.ToString() 方法;

    該操作在每次調用時都返回不同的結果,即使傳入的參數不變。如:Guid.NewGuid 方法在每次都返回不同的值;

    該操作有嚴重的、顯而易見的副作用;

    該操作返回內部狀態的一個副本(這不包括那些在棧上返回的實值型別對象的副本);

    該操作返回一個數組。

 

5.2 屬性的設計

  要建立唯讀屬性 - 如果調用方不應該改變屬性的值。

  不要提供唯寫屬性,也不要讓 setter 的可訪問性比 getter 更廣。

  要為所有的屬性提供合理的預設值,這樣可以確保預設值不會導致安全性漏洞或效率低下的代碼。

  要允許使用者以任何順序來設屬性的值,即使這可能會使對象在短時間內處於無效狀態。

  要保留屬性原來的值,如果屬性的 setter 拋出異常。

  避免在屬性的 getter 中拋出異常。

  考慮通過索引器的方式讓使用者訪問儲存在呢不數組中的資料。

  考慮為代表元素集合的類型提供索引器。

  避免使用有一個以上參數的索引屬性。

  避免用 System.Int32、System.Int64、System.String、System.Object、枚舉或泛型參數之外的類型來作索引器的參數。

  要將 Item 名稱用於索引屬性,除非有明顯更好的名字(例如 System.String 的 Chars 屬性)。

  不要同時提供語義上等價的索引器和方法。

  不要在一個類型中提供具有不同名字的索引器。

  不要使用非預設的索引屬性。

  考慮在高層 API 的屬性值被修改時觸發屬性改變的通知事件。

  考慮在屬性值被外界修改時觸發通知事件。

  

5.3 建構函式的設計

  考慮提供簡單的建構函式,最好是預設建構函式。

  考慮用靜態Factory 方法來代替建構函式 - 如果無法讓想要執行的操作的語義與新執行個體的建構函式直接對應,或者遵循建構函式的設計規範會讓人感覺不合理。

  要把建構函式的參數列表當做設定主要屬性的快捷方法。

  要用相同的名字來命名建構函式的參數和屬性 - 如果定義該建構函式參數的目的就是為了設定對應的屬性。

  要在建構函式中做最少的工作。

  要在適當的時候從執行個體建構函式中拋出異常。

  要在類中顯式地聲明公有的預設建構函式 - 如果這樣的建構函式是必需的。 

  避免在結構中顯式地定義預設建構函式。

  避免在對象的建構函式內部調用虛成員。

  要把靜態建構函式聲明為私人。

  不要從靜態建構函式中拋出異常。

  考慮以內聯的形式來初始化靜態欄位,而不要顯式地定義靜態建構函式,這是因為運行庫能夠對那些沒有顯示定義靜態建構函式的類型進行效能最佳化。

 

5.4 事件的設計

  要在事件中使用術語“raise”,而不要使用“fire”或“trigger”。

  要用 System.EventHandler<T> 來定義事件處理函數,而不是手工建立新的委託來定義事件處理函數。

  考慮用 EventArgs 的子類來做事件的參數,除非百分之百確信該事件不需要給事件處理方法傳遞任何資料,在這種情況下可以直接使用 EeventArgs。

  要用受保護的虛方法來觸發事件。這隻適用於非密封類中的非靜態事件,不適用於結構、密封類以及靜態事件。

  要讓觸發事件的受保護的方法帶一個參數,該參數的類型為事件參數類,該參數的名字應該為 e。

  不要在觸發非靜態事件時把 null 作為 sender 參數傳入。

  要在觸發靜態事件時把 null 作為 sender 參數傳入。

  不要在觸發事件時把 null 作為資料參數傳入。

  考慮觸發能夠被終端使用者取消的事件,這適用於前置事件。

  要把事件處理函數的傳回型別定義為 void。

  要用 object 作為事件處理函數的第一個參數的類型,並將其命名為 sender。

  要用 System.EventArgs 或其子類作為事件處理函數的第二個參數的類型,並將其命名為 e。

  不要在事件處理函數中使用兩個以上的參數。

  

5.5 欄位的設計

  不要提供公有的或受保護的執行個體欄位。

  要用常量欄位來表示永遠不會改變的常量。

  要用公有的靜態唯讀欄位來定義預定義的對象執行個體。

  不要把可變類型的執行個體賦值給唯讀欄位。

  

5.6 擴充方法

  避免草率地定義擴充方法,尤其是為別人的類型定義擴充方法。

  考慮在下面的情境中使用擴充方法。

  為一個介面的所有實現提供相關的輔助方法,而且這些功能可以通過核心介面來表達。

  如果增加一個執行個體方法會引入對其它類型的依賴關係,而依賴關係會破壞依賴關係的管理規則,那麼應該使用擴充方法。

  避免為 System.Object 定義擴充方法。

  不要把擴充方法和被擴充的類型放在同一個命名空間中 - 除非是為了把方法增加到介面中,或是為了對依賴關係進行管理。

  避免在定義兩個擴充方法時使用相同的簽名,即使它們位於不同的命名空間。

  考慮把擴充方法和被擴充的類型放在同一個命名空間 - 如果被擴充的類型是介面,而且該擴充方法的設計目的就是要用於大多數的情況甚至是所有的情況。

  不要把實現某個特性的擴充方法放在一個通常與其他特性相關聯的命名空間中。相反,該特性屬於哪個命名空間,就應該把對應的擴充方法放在那裡。

  避免使用太寬泛的名字(例如“Extensions”)來給擴充方法專用的命名空間命名,要使用更具描述性的名字(比如“Routing”)。

  

5.7 操作符重載

  避免定義操作符重載,除非該類型讓人感覺像個基本(內建)類型。

  考慮在讓人感覺應該想基本類型的類型中定義操作符重載。

  要為表示數值的結構(比如 System.Decimal)定義操作符重載。

  不要在定義操作符重載時耍小聰明。

  不要提供操作符重載,除非至少有一個運算元的類型是定義該操作符重載的類型。

  要以對稱的方式來重載操作符。

  考慮為每個重載過的操作符提供對應的方法,並用容易理解的名字來命名。

  不要提供類型轉換操作符 - 如果沒有明確的使用者需求。

  不要在定義類型轉換操作符時超越類型所在的領域。

  不要提供隱式類型轉換操作符 - 如果這樣的類型轉換可能會丟失精度。

  不要從隱式的強制類型轉換操作符中拋出異常。

  要拋出 System.InvalidCastException - 如果對強制類型轉換操作符的調用會丟失精度而該操作符承諾不丟失精度。

 

5.8 參數的設計

  要用類階層中最接近基類的類型作為參數的類型,同時要保證該類型能夠提供成員所需的功能。

  不要使用保留參數。

  不要把指標、指標數組及多維陣列作為公有方法的參數。

  要把所有的輸出參數放在所有以值方式和以引用方式傳遞的參數的後面(不包括參數數組),即使這樣會在重載成員之間導致參數順序不一致也要如此。

  要在覆蓋成員或者實現介面成員時保持參數命名的一致。

  要用枚舉 - 如果不這樣做會導致參數中有兩個或兩個以上的布爾類型。

  不要使用布爾參數,除非百分之百肯定絕對不需要兩個以上的值。

  考慮在建構函式中,對確實只有兩種狀態的參數以及用來初始化布爾屬性的參數使用布爾類型。

  要對傳給共有的、受保護的或顯式實現的成員的參數進行驗證。如果驗證失敗,那麼應該拋出 System.ArgumentException 或其子類。

  要拋出 ArgumentNullExcepytion - 如果傳入的是 null 而該成員不支援 null。

  要驗證枚舉參數。

  不要用 Enum.IsDefined 來檢查枚舉的範圍。

  要清楚地知道傳入的可變參數可能會在驗證後發生改變。

  避免使用輸出參數或引用參數。

  不要以引用方式傳遞參考型別。

  考慮給數組參數增加 params 關鍵字 - 如果預計使用者會傳入為數不多的數組元素。

  避免使用 params 數組參數 - 如果絕大多數時候調用方要傳入的數組元素本來就已經在一個數組中了。

  不要使用 params 數組參數 - 如果要在成員中對數組進行修改。

  考慮在簡單的重載中使用 params 關鍵字,儘管更複雜的重載不能用 params 關鍵字。

  要對參數進行合理的排序,以便使用 params 關鍵字。

  考慮在對效能要求非常高的 API 中為參數數量較少的調用提供特殊的重載和相應的實現。

  要注意傳入的 params 數組參數可能是 null。

  不要使用 varargs 方法,又稱省略符號。

  要為任何以指標為參數的成員提供一個替補成員,這是因為指標不符合 CLS 規範 規範。

  避免對指標參數進行高開銷的檢查。

  要在設計用到指標的成員時遵循與指標相關的常用約定。

  

《.NET 設計規範》第 5 章:成員設計

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.