Методы расширенияExtension Methods

Методы расширения — это функция языка, которая позволяет вызывать статические методы с помощью синтаксиса вызова метода экземпляра.Extension methods are a language feature that allows static methods to be called using instance method call syntax. Эти методы должны принимать по крайней мере один параметр, представляющий экземпляр, с которым должен выполняться метод.These methods must take at least one parameter, which represents the instance the method is to operate on.

Класс, определяющий такие методы расширения, называется классом спонсора и должен быть объявлен статическим.The class that defines such extension methods is referred to as the "sponsor" class, and it must be declared as static. Чтобы использовать методы расширения, необходимо импортировать пространство имен, определяющее класс спонсора.To use extension methods, one must import the namespace defining the sponsor class.

X AVOID frivolously определяет методы расширения, особенно на типах, вы не являетесь его владельцем.X AVOID frivolously defining extension methods, especially on types you don’t own.

Если вы владеете исходным кодом типа, рассмотрите возможность использования обычных методов экземпляра.If you do own source code of a type, consider using regular instance methods instead. Если вы не владеете и хотите добавить метод, будьте внимательны.If you don’t own, and you want to add a method, be very careful. Широкие возможности использования методов расширения имеют потенциал ненужных интерфейсов API типов, которые не предназначены для этих методов.Liberal use of extension methods has the potential of cluttering APIs of types that were not designed to have these methods.

✓ CONSIDER с помощью методов расширения в следующих сценариях:✓ CONSIDER using extension methods in any of the following scenarios:

  • Для предоставления вспомогательных функций, относящихся к каждой реализации интерфейса, если говорят, что функциональность может быть написана с точки зрения базового интерфейса.To provide helper functionality relevant to every implementation of an interface, if said functionality can be written in terms of the core interface. Это обусловлено тем, что в противном случае конкретные реализации не могут быть назначены интерфейсам.This is because concrete implementations cannot otherwise be assigned to interfaces. Например, операторы LINQ to Objects реализуются как методы расширения для всех типов IEnumerable<T>.For example, the LINQ to Objects operators are implemented as extension methods for all IEnumerable<T> types. Таким же, любая реализация IEnumerable<> автоматически включает LINQ.Thus, any IEnumerable<> implementation is automatically LINQ-enabled.

  • Когда метод экземпляра вводит зависимость от какого-либо типа, но такая зависимость приведут к нарушению правил управления зависимостями.When an instance method would introduce a dependency on some type, but such a dependency would break dependency management rules. Например, зависимость от String к System.Uri, вероятно, нежелательна, и поэтому String.ToUri() метод экземпляра, возвращающий System.Uri, будет неверной структурой с точки зрения управления зависимостями.For example, a dependency from String to System.Uri is probably not desirable, and so String.ToUri() instance method returning System.Uri would be the wrong design from a dependency management perspective. Статический метод расширения, Uri.ToUri(this string str) возвращающий System.Uri, является гораздо более лучшей конструкцией.A static extension method Uri.ToUri(this string str) returning System.Uri would be a much better design.

X AVOID определения методов расширения в System.Object.X AVOID defining extension methods on System.Object.

Visual Basic пользователи не смогут вызывать такие методы для ссылок на объекты с помощью синтаксиса метода расширения.Visual Basic users will not be able to call such methods on object references using the extension method syntax. Visual Basic не поддерживает вызов таких методов, поскольку в Visual Basic объявление ссылки как объекта заставляет все вызовы методов в нем быть поздним связыванием (фактический член определяется во время выполнения), а привязки к методам расширения определяются в время компиляции (с ранним связыванием).Visual Basic does not support calling such methods because, in Visual Basic, declaring a reference as Object forces all method invocations on it to be late bound (actual member called is determined at runtime), while bindings to extension methods are determined at compile-time (early bound).

Обратите внимание, что это правило применяется к другим языкам, где имеется такое же поведение привязки, или если методы расширения не поддерживаются.Note that the guideline applies to other languages where the same binding behavior is present, or where extension methods are not supported.

X DO NOT размещения методов расширения в пространстве имен, расширенного типа, если он предназначен для добавления методов в интерфейсах или для управления зависимостями.X DO NOT put extension methods in the same namespace as the extended type unless it is for adding methods to interfaces or for dependency management.

X AVOID определение два или несколько методов расширения с такой же сигнатурой, даже если они находятся в разных пространствах имен.X AVOID defining two or more extension methods with the same signature, even if they reside in different namespaces.

✓ CONSIDER определение методов расширения в пространстве имен, расширенный тип, если тип является интерфейсом и методы расширения предназначены для использования в большинство или все случаи.✓ CONSIDER defining extension methods in the same namespace as the extended type if the type is an interface and if the extension methods are meant to be used in most or all cases.

X DO NOT определяет расширение методов реализации функции в пространствах имен, обычно связанные с другими компонентами.X DO NOT define extension methods implementing a feature in namespaces normally associated with other features. Вместо этого определите их в пространстве имен, связанном с компонентом, к которому они относятся.Instead, define them in the namespace associated with the feature they belong to.

X AVOID универсального именования пространств имен, выделенных для методов расширения (например, «расширения»).X AVOID generic naming of namespaces dedicated to extension methods (e.g., "Extensions"). Вместо этого используйте описательное имя (например, "Routing").Use a descriptive name (e.g., "Routing") instead.

Части © 2005, 2009 Корпорация Майкрософт. Все права защищены.Portions © 2005, 2009 Microsoft Corporation. All rights reserved.

Перепечатано с разрешения Pearson Education, Inc. из книги Инфраструктура программных проектов. Соглашения, идиомы и шаблоны для многократно используемых библиотек .NET (2-е издание), авторы: Кржиштоф Цвалина (Krzysztof Cwalina) и Брэд Абрамс (Brad Abrams). Книга опубликована 22 октября 2008 г. издательством Addison-Wesley Professional в рамках серии, посвященной разработке для Microsoft Windows.Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by Addison-Wesley Professional as part of the Microsoft Windows Development Series.

См. также:See also