【進階修鍊】——改善C#程式品質(6)

來源:互聯網
上載者:User

標籤:使用   ar   on   代碼   ad   new   應用   as   設計   

90,不應為抽象類別指定public的建構函式。

抽象類別即使指定了public的建構函式,也是不能執行個體化的,編譯通不過。抽象類別的建構函式應該設定為protected,它的作用應該是初始化自己的成員,以及可以被子類建構函式調用。設定為public許可權毫無意義。 91,可見欄位應該重構為屬性。

屬性比欄位有更好的靈活性,可以加入代碼控制,可以在類型內部實現安全執行緒訪問,可以讓類型得到通知(如WPF系統),這些都是欄位所不具備的。當然,如果僅限於類型內部使用,應該用欄位。 92,謹慎將數組或集合作為屬性。

即使這個屬性是唯讀(沒有set方法),那也只是針對集合的引用而已,集合內部的元素是可以被改變的。我們可以將集合作為私人變數儲存,然後提供必要的方法來訪問這個集合。如果非要公開這個集合,也要設定為唯讀屬性。 93,構造方法應初始化主要屬性和欄位。

初始化器實際上就是在建構函式代碼塊的前面插入一些代碼來執行初始化操作,我們應該為必要的欄位和屬性提供一個初始值,而不要使用時得到一個null值。 94,區分override和new關鍵字。

Override是實現多態的關鍵,子類的方法前面有override關鍵字,則子類的對象將調用該方法。如果子類的方法前有new關鍵字,則該方法是獨立於基類的新方法,父類型的引用不會調用該方法,而只能調用父類的方法。 95,不要在建構函式中調用虛成員。

虛成員被子類重寫後可能用到子類的成員變數,而父類的建構函式是優先於子類建構函式執行的,這時,子類的成員變數還沒有得到初始化,會引發Null異常。 96,成員應優先考慮公開基底類型或介面。

比如方法或屬性返回介面,我們以後改變了內部的實現細節,外部代碼根本不用修改,可以獲得更好的靈活性。另外,可以進一步控製成員的可見度,將可見度限制得更低。 97,優先考慮基底類型或介面作為參數傳遞。

上面一條是考慮成員的可見度,這一條建議是考慮函數的適用範圍,抽象越高,通用性越好。 98,用params減少重複的參數。

如果參數個數不定,參數類型又一致,可以考慮params減少參數數量。 99, 重寫時不要使用子類參數。

也就是不要改變重寫方法的參數類型。事實上改變了參數的類型,被認為是兩個不同的方法了。 100, 靜態方法和執行個體方法沒有區別。

這一點初看有點納悶,它是指靜態方法和執行個體方法都是被分配到類型的方法表上的。靜態方法在多線程環境中也需要考慮方法內部的線程同步,和執行個體方法是一樣的。靜態方法也需要類型對象被分配才能執行,而這一步是我們第一次用到類型的時候CLR為我們自動建立的,我們感覺不到而已。 101, 使用擴充方法,為類型“添加”方法。

擴充方法本質是靜態函數,它只能被放在靜態類中,使用它可以減少我們的繼承體繫結構,我們可以對密封類,第三方提供的類,甚至介面使用擴充方法,使得這些方法看起來好像就是它們自己的一樣,而不需修改類的內部結構。擴充方法實際上是靜態函數的一種文法糖,但是有了擴充方法,我們使用類會變得更加自然,更加物件導向。 102,區分抽象類別和介面的適用場合。

介面支援多繼承,抽象類別則不能。介面只包含聲明,不能實現,抽象類別則可以。介面增加成員後,所有的繼承者都必須重構,抽象類別則不用。所以,介面一旦設計好就應該是儲存不變的,功能儘可能單一,以利於重用。如果對象間多個功能相近且關係緊密,應該使用抽象類別。如果對象間關係不緊密,但若干功能有共同的聲明,則使用介面。抽象類別解決的是“Is a”關係,介面解決的是“Can do”關係。 103,區分組合和繼承的應用場合。

繼承帶來的多態性是它相較於組合的優勢,但是在大多數的應用場合,我們都不需要多態。繼承代表的是“Is a”,組合代表的是“Has a”,這是兩種不同的設計理念。繼承能提高代碼的可重用性,比如上面建議中的為函數的傳回值和參數指定基底類型,可以提高函數的適用範圍。但是繼承也有缺點,繼承了太多的方法和屬性,這些方法和屬性都會被曝露出來,給使用者帶來麻煩,同時也破壞了封裝性。組合具有更好的封裝性,我們只提供必要的方法和屬性。 104,用多態代替條件陳述式。

多個case語句的函數,如果添加分支,這個函數就會被修改,如果考慮多態,我們只需添加一個新的類。這就實現了物件導向的“開閉原則”,對修改關閉,對擴充開放。當然這一步,往往不是設計初期就考慮的到的,經常在重構代碼的過程中來實現的。 105,使用私人建構函式強化單例。

在實現Singleton模式時,應只提供一個private的建構函式。 106,為靜態類添加靜態建構函式。

靜態建構函式只執行一次,不能帶參數,代碼無法調用它。靜態建構函式可以對異常進行捕獲,如若用靜態初始化器則不能捕獲異常。 107,區分靜態類和單例。

單例是一個類的執行個體,而靜態類不是。靜態類沒有繼承和多態的特性。 108,將類型標識為sealed。

如果確信類不會被繼承了,就應該將其標為sealed,避免被其他類型繼承,控制繼承的深度。另外,標記為sealed的類型,成員的protected關鍵字已經沒有意義了。 109,謹慎使用嵌套類。

當某個類型需要訪問另一個類型的私人成員是可以將其設計為嵌套類,嵌套類可以訪問外部類的私人成員。並且要始終注意,確保嵌套類為private的,即它的可見度只能限定於外部類型內部。 110,用類來代替Enum。

這看起來有點奇怪。它的出發點是類比枚舉擁有更多的可擴充能力,可以添加更多的附加資訊。如果沒有這些附加資訊,則應該使用枚舉,枚舉是實值型別,效率更高。具體的實現方法是,讓類的建構函式為private,並提供public static readonly 的各個枚舉類。 111, 避免雙向耦合。

即兩個類型間的互相引用。如果兩個類型在不同的項目中,則會造成迴圈參照。解除雙向耦合的方式就是提取一個公用的介面,讓他們都去依賴這一個介面。 112, 將現實世界中的對象抽象為類,將可複用的對象圈起來就是命名空間。

這一點要求我們對類要有一定的組織,否則代碼會越來越混亂。

【進階修鍊】——改善C#程式品質(6)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.