擴展方法(Extension Methods)是C#3.0時引入的新特性,相信很多人都聽過並且也都用過,最常見的是在LINQ中的使用。 不僅如此,在開發中,我們也可以創建自己擴展方法,使用它來優化類的設計、簡化代碼。本文將簡單地介紹擴展方法的概念、定義、使用場景以及要註意的點。 不僅如此,在開發中, ...
擴展方法(Extension Methods)是C#3.0時引入的新特性,相信很多人都聽過並且也都用過,最常見的是在LINQ中的使用。
不僅如此,在開發中,我們也可以創建自己擴展方法,使用它來優化類的設計、簡化代碼。本文將簡單地介紹擴展方法的概念、定義、使用場景以及要註意的點。
一、概念
擴展方法是一種特殊類型的靜態方法。對於一個C#類型,如類(包括密封類)、值類型、介面等,擴展方法可以在不改變該類型源碼的前提下,為它的實例提供新的成員。因此,若要為一個框架或第三方庫的某個類型增加輔助功能,通過擴展方法就可以輕而易舉地實現,這也是“擴展”的意義所在。二、如何定義
創建擴展方法很簡單,有以下幾個步驟:1、創建一個靜態類;
2、在其中創建一個靜態方法;
3、為這個靜態方法添加至少一個參數,併在第一個參數前加上this關鍵字,這個關鍵字會告訴編譯器當前方法是一個擴展方法。而這個方法將成為第一個參數所屬類型的新成員。
以下一個典型的擴展方法,用於為枚舉值提供一個可獲取其DescriptionAttribute特性值的方法:
註意:只有在引用擴展方法所在的靜態類的命名空間後,才能使用它;否則,直接調用會編譯失敗。上例中,使用該擴展方法要引用TLA.Infrastructure.Extensions命名空間。
三、何時使用
從擴展方法的概念上,不難看出,它可以用在以下幾種場合:1、要為某個類型擴展功能,但沒有其源碼,比如某個框架或第三方庫中的一個類;例如,想要獲取一個列表中所有的奇數項,就可以為IList<T>介面增加一個擴展方法,這裡的IList<T>介面本身是.NET框架中的介面。
2、即使可以訪問原有類型的源碼,也可以使用擴展方法為它添加輔助功能;
3、重用代碼,使代碼更簡潔;由於擴展方法封裝了一段完整的邏輯,所以,使用擴展方法就避免了複製粘貼代碼的情況。上例中擴展方法的內容也符合這種使用場景。
四、註意事項
以下是定義與使擴展方法時的一些註意事項和最佳實踐:1、擴展方法本質上是為原有類型提供輔助功能,因此,在創建時,要確保它具有實際意義,且遵循單一職責原則;也即,不能過度使用擴展方法並且它能夠完成一個具體、完整的功能;
2、擴展方法本身具有通用性,因此,它裡面應避免特定的業務數據類型及其相關邏輯;
3、如果為介面增加擴展方法,擴展方法的命名空間可以與介面的一致;否則,應儘量避免與原類型寫在同一命名空間下,這樣會“污染”原類型。建議的做法是為擴展方法所在的類設定一個單獨的命名空間,如:<Company>.<Product>.Extentions。不過,這樣做也有缺點:在操作原有類型的實例時,如果不引用擴展方法所在的命名空間,那麼,它就不容易被髮現,而解決這個問題的辦法是,儘量將擴展方法文檔化,並告訴項目組的其他開發人員;
4、為介面增加擴展方法後,則所有實現此介面的類都會包含該擴展方法;
5、在擴展方法中,要對第一個參數進行非空檢查,如果為空,應拋出ArgumentNullException(參數為空)異常。