擴充方法

擴充方法是語言功能,允許使用實例方法呼叫語法呼叫靜態方法。 這些方法必須採用至少一個參數,這表示方法所要操作的實例。

定義這類擴充方法的類別稱為「贊助者」類別,而且必須宣告為靜態。 若要使用擴充方法,您必須匯入定義贊助者類別的命名空間。

❌ 避免不小心定義擴充方法,特別是在您不擁有的類型上。

如果您擁有類型的原始程式碼,請考慮改用一般實例方法。 如果您沒有擁有,而且想要新增方法,請非常小心。 擴充方法的使用可能很雜亂,而這些 API 不是設計為具有這些方法的類型。

✔️ 請考慮在下列任何案例中使用擴充方法:

  • 若要提供與介面的每個實作相關的協助程式功能,如果上述功能可以用核心介面撰寫。 這是因為無法將具體實作指派給介面。 例如, LINQ to Objects 運算子會實作為所有 IEnumerable<T> 類型的擴充方法。 因此,任何 IEnumerable<> 實作都會自動啟用 LINQ。

  • 當實例方法導入某些類型的相依性時,這類相依性會中斷相依性管理規則。 例如,從 StringSystem.Uri 的相依性可能不想要,因此 String.ToUri() 從相依性管理的觀點傳回 System.Uri 實例方法會是錯誤的設計。 傳回 System.Uri 的靜態擴充方法 Uri.ToUri(this string str) 會是較佳的設計。

❌ 避免在 上 System.Object 定義擴充方法。

VB使用者將無法使用擴充方法語法,在物件參考上呼叫這類方法。 VB不支援呼叫這類方法,因為在VB中,將參考宣告為 Object 會強制其上的所有方法調用成為晚期繫結, (呼叫的實際成員是在執行時間判斷) ,而擴充方法的系結是在編譯時期 (早期系結) 決定。

請注意,指導方針適用于存在相同系結行為的其他語言,或不支援擴充方法。

❌ 請勿將擴充方法放在與擴充型別相同的命名空間中,除非將方法新增至介面或相依性管理。

❌ 避免使用相同的簽章定義兩個或多個擴充方法,即使它們位於不同的命名空間也一樣。

✔️ 如果類型是介面,且擴充方法應該用於大部分或所有案例,請考慮在與擴充型別相同的命名空間中定義擴充方法。

❌ DO NOT 定義擴充方法,以實作通常與其他特徵相關聯的命名空間中的功能。 相反地,請在與其所屬功能相關聯的命名空間中定義它們。

❌ 避免 (專用於擴充方法的命名空間泛型命名,例如「Extensions」) 。 請改用描述性名稱 (例如「路由」) 。

Portions © 2005, 2009 Microsoft Corporation. 著作權所有,並保留一切權利。

獲 Pearson Education, Inc. 的授權再版,從 Krzysztof Cwalina 和 Brad Abrams 撰寫,並在 2008 年 10 月 22 日由 Addison-Wesley Professional 出版,作為 Microsoft Windows Development Series 一部份的 Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition 節錄。

另請參閱