1. 程式人生 > >《.NET 設計規範》第 4 章:類型設計規範

《.NET 設計規範》第 4 章:類型設計規範

這樣的 方法 開放 flags 包含 困難 自由 權限 center

第 4 章:類型設計規範

4.1 類型和命名空間

  要用命名空間把類型組織成一個由相關的功能區所構成的層次結構中。

  避免非常深的命名空間層次。因為用戶需要經常回找,所以這樣的層次瀏覽起來很困難。

  避免有太多的命名空間。

  避免把為高級方案而設計的類型和為常見編程任務而設計的類型放在同一個命名空間中。

  不要不指定類型的命名空間就定義類型。

  要把那些為基本命名空間提供設計時功能的類型放在帶“.Design”後綴的命名空間中。

  要把那些為基本命名空間提供自定義權限的類型放在帶“.Permissions”後綴的命名空間中。

  要把那些為基本命名空間提供互操作功能的類型放在帶“.Interop”後綴的命名空間中。

  要把所有位於主互操作程序集中的代碼放在帶“.Interop”後綴的命名空間中。

4.2 類和結構之間的選擇

  考慮定義結構而不要定義類 - 如果該類型的實例比較小而且聲明周期比較短,或者是經常被內嵌在其它對象中。

  避免定義結構,除非該類型具有以下所有特征。

    它在邏輯上代表一個獨立的值,與基本類型(int、double 等等)相似;

    它的實例的大小小於 16 個字節;

    它是不可變的;

    它不需要經常被裝箱。

  

4.3 類和接口之間的選擇

  要優先定義類而不是接口

  要用抽象類而不是用接口來解除契約與實現之間的耦合。

  要定義接口 - 如果需要提供多態層次結構的值類型的話。

  考慮通過定義接口來達到與多重繼承相類似的效果。

  

4.4 抽象類的設計

  不要在抽象類型中定義公有的或內部受保護的構造函數。

  要為抽象類定義受保護的構造函數或內部構造函數。

  要為每個抽象類提供至少一個繼承自該抽象類的具體類型。

  

4.5 靜態類的設計

  要盡量少用靜態類。

  不要把靜態類當做是雜物箱。

  不要聲明或覆蓋靜態類中的實例成員。

  要把靜態類定義為密封的、抽象的,並添加一個私有的實例構造函數 - 如果編程語言不直接支持靜態類。

  

4.6 接口的設計

  要定義接口 - 如果想讓一組包括值類型在內的類型支持一些公共的 API。

  考慮定義接口 - 如果想讓已經繼承自其它基類的類型支持該接口提供的功能。

  避免使用記號接口(沒有成員的接口)。

  要為接口提供至少一個實現該接口的類型。

  要為每個接口提供至少一個使用該接口的 API(一個以該接口為參數的方法,或是一個類型為該接口的屬性)。

  不要給已經發行的接口再添加成員。

4.7 結構的設計

  不要為結構提供默認的構造函數。

  不要定義可變的值類型。

  要確保當結構實例的所有數據都為 0、false 或 null(如果合適)時,結構仍處於有效狀態。

  要為值類型實現 IEquatable<T>。

  不要顯式地擴展 System.ValueType,事實上大多數編程語言不允許這樣做。

4.8 枚舉的設計

  要用枚舉來加強那些表示值的集合的參數、屬性以及返回值的類型性。

  要優先使用枚舉而不要使用靜態常量。

  不要把枚舉用於開放的集合(比如操作系統的版本、朋友的名字等)。

  不要提供為了今後使用而保留的枚舉值。

  避免顯示地暴露只有一個值的枚舉。

  不要在枚舉中包含 sentinel 值。

  要為簡單枚舉類型提供零值。

  考慮以 Int32 為載體來實現枚舉(大多數編程語言的默認選擇),除非下面的任何一條成立。

  要用復數名詞或名詞短語來命名標記枚舉,用單數名詞或名詞短語來命名簡單枚舉。

  不要直接擴充 System.Enum。

  要對標記枚舉使用 System.FlagsAttribute。不要把該修飾屬性用於簡單枚舉。

  要用 2 的冪次方作為標記枚舉的值,這樣就可以使用按位 OR 操作來自由地組合他們。

  考慮為常用的標記組合提供特殊的枚舉值。

  避免讓創建的標記枚舉包含某些無效的組合。

  避免把 0 用作標記枚舉的值,除非該值表示“所有標記都被清除”,而且按下一條規範進行了適當地命名。

  要把標記枚舉的 0 值命名為 None。對標記枚舉來說,該值必須始終表示“所有標記均被清除”。

  考慮給枚舉添加值,盡管要冒一點兼容性的風險。

  

4.9 嵌套類型

  要在想讓一個類型能夠訪問外層類型的成員時才使用嵌套類型。

  不要用公共嵌套類型來進行邏輯分組,應該用命名空間來達到這一目的。

  避免公開地暴露嵌套類型。除非是只需在極少數的情況下聲明嵌套類型的變量,比如派生子類時,或者其它需要定制的高級場景中。

  不要使用嵌套類型 - 如果該類型可能會被除了它的外層類型之外的類型引用。

  不要使用嵌套 - 如果需要讓客戶代碼來實例化它們。如果某個類型具有公有構造函數,那麽他不應該被嵌套在其它類型中。

  不要把嵌套類型定義為接口的成員,許多編程語言不支持這樣做。

4.10 類型和程序集元數據

  要在包含公共類型的程序集中使用 CLSCompliant(true) 修飾屬性。

  要在包含公共類型的程序集中使用 AssemblyVersionAttribute 修飾屬性。

  考慮在程序集版本號中使用 <V>、<S>、<B>、<R> 的格式。其中 V 是主版本號,S 是服務版本號,B 是構建號,R 是構建修訂號。

  要在程序集中使用下面的修飾屬性來提供額外的信息。

  考慮在程序集中使用 ComVisible(false)。可供 COM 調用的 API 需要特別地設計。

  考慮在程序集這種使用 AssemblyFileVersionAttribute 和 AssemblyCopyrightAttribut,其目的是為了提供與程序集有關的額外信息。

《.NET 設計規範》第 4 章:類型設計規範