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

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Метод расширения (англ. extension method) в программировании — метод, добавляемый к существующему классу (типу) в месте, отличном от модуля объявления класса. Синтаксический сахар для модуля расширения был введён в C# 3.0 и VB.NET.

Метод расширения не следует путать с относящему к наследованию понятием расширения метода (англ. method extension), существующего в языках CLOS, Smalltalk, Beta, при котором метод суперкласса вызывается до, во время или после вызова метода класса[1].

Реализация в C#[править | править вики-текст]

Следующий пример показывает метод расширения, определённый для класса System.String (в языке C# имеет псевдоним string). Заметим, что он определён внутри невложенного и ненастраиваемого статичного класса[2]:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        // метод WordCount принимает на вход строку, возвращает число слов, т.е. число подстрок, разделённых пробелом, точкой или вопросительным знаком.
        public static int WordCount(this string str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}
 
/* Метод-расширение WordCount появится в области видимости, если подключить соответствующее пространство имён: */
using ExtensionMethods;
 
/* Теперь его можно вызвать: */
string s = "Hello Extension Methods";
int i = s.WordCount(); // i получит значение 3
int j = "Съешь же ещё этих мягких французских булок, да выпей чаю.".WordCount(); // j получит значение 10

В сравнении с обычным методом, метод расширения статичен, а первый параметр содержит после this целевой класс и переменную целевого класса, после чего могут следовать параметры метода[3].

В C# метод расширения имеет доступ только к публичным членам класса. Другим ограничением является то, что если есть и встроенный метод, и расширение, приоритет даётся встроенному методу[3].

Методы расширения широко используются в LINQ. Например, оператор Select является методом расширения интерфейса IEnumerable[4].

Реализация в Visual Basic .NET[править | править вики-текст]

В Visual Basic .NET методы расширения позволяют разработчикам добавлять новые возможности типам данных без образования производных типов. Метод расширения может быть только процедурой вида Sub или Function, но не свойством, полем или событием. Первый аргумент метода указывает целевой тип данных для расширения. Методы расширения могут определяться только внутри модулей. Как и в C#, метод экземпляра имеет преимущество перед методом расширения, даже если последний обладает более точной сигнатурой[5].

Реализация в Ruby[править | править вики-текст]

Язык Ruby имеет аналогичную C# 3.0 возможность, называемую «открытый класс» (англ. open class)[6].

class TestClass
  def method1
  end
 
  def method2
  end
end
 
test = TestClass.new
test.method1
test.method2
 
class TestClass
  def method3
  end
end
 
test.method3

Кроме того, метод расширения можно добавить не ко всему классу, а только конкретному экземпляру. Более того, в JRuby можно добавить метод к классу из Java[6]. В Ruby, если есть и встроенный метод, и расширение, приоритет дается расширенному методу.

Реализация в других языках[править | править вики-текст]

В распространённых динамических языках (JavaScript, Perl, Python, Ruby) механизм метода расширения уже давно может быть реализован (со всеми мерами предосторожности) путём «обезьяньего патча»[7].

Примечания[править | править вики-текст]

Литература[править | править вики-текст]

  • Liberty, J. and Xie, D. Programming C# 3.0. — O'Reilly Media, 2007. — P. 294-297. — 608 p. — ISBN 9780596554880.
  • Papa, J. Data-Driven Services with Silverlight 2. — O'Reilly Media, 2008. — P. 12-14. — 368 p. — ISBN 9780596554422.
  • Gardner, T.A. Inheritance Relationships for Disciplined Software Construction. — Springer, 2002. — ISBN 9781852334673.
  • Bai, Y. Practical Database Programming with Visual Basic.NET. — Wiley, 2012. — P. 229-232. — 900 p. — ISBN 9781118249826.

Ссылки[править | править вики-текст]