Что такое методы расширения в .NET?
EDIT: Я опубликовал следующий вопрос в Использование методов расширения
Что такое методы расширения в .NET?
EDIT: Я опубликовал следующий вопрос в Использование методов расширения
Методы расширения позволяют разработчикам добавлять новые методы к общедоступному контракту существующего типа CLR без необходимости подкласса его или перекомпиляции исходного типа.
Методы расширения помогают сочетать гибкость поддержки "утиной типизации", популярной сегодня в динамических языках, с производительностью и проверкой во время компиляции строго типизированных языков.
Ссылка: http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx
Вот пример метода расширения (обратите внимание на ключевое слово this
перед первым параметром):
public static bool IsValidEmailAddress(this string s)
{
Regex regex = new Regex(@"^[\w-\.][email protected]([\w-]+\.)+[\w-]{2,4}$");
return regex.IsMatch(s);
}
Теперь указанный выше метод может быть вызван напрямую из любой строки, например:
bool isValid = "[email protected]".IsValidEmailAddress();
Добавленные методы также появятся в IntelliSense:
(источник: scottgu.com)
Что касается практического использования методов расширения, вы можете добавить новые методы в класс, не создавая новый класс.
Взгляните на следующий пример:
public class Extended {
public int Sum() {
return 7+3+2;
}
}
public static class Extending {
public static float Average(this Extended extnd) {
return extnd.Sum() / 3;
}
}
Как видите, класс Extending
добавляет метод с именем Average к классу Extended
. Чтобы получить среднее значение, вы вызываете метод average
, так как он принадлежит extended
классу:
Extended ex = new Extended();
Console.WriteLine(ex.average());
Предположим, у меня есть собака. Все собаки - все животные типа собаки - делают определенные вещи:
Вещи, которые может делать собака, называются "методами".
Теперь давайте предположим, что Великий Программист в OO Heaven забыл добавить метод к классу собаки: FetchNewspaper(). Вы хотите быть в состоянии сказать:
rex.FetchNewspaper(); // or
wolfie.FetchNewspaper(); // or
beethoven.FetchNewspaper();
...... даже если у вас нет доступа к исходному коду.
Как дела, чтобы ваша собака сделала это? Ваше единственное решение - создать "метод расширения".
(Обратите внимание на ключевое слово "this" перед первым параметром ниже):
public static void FetchNewsPaper(this Dog familyDog)
{
Console.Writeline("Goes to get newspaper!")
}
И если вы хотите, чтобы ваша собака получила газету, просто сделайте это:
Dog freddie_the_family_dog = new Dog();
freddie_the_family_dog.FetchNewspaper();
Вы можете добавить метод в класс, не имея исходного кода. Это может быть очень удобно!
Методы расширения - это способы для разработчиков "добавлять" методы к объектам, которые они не могут контролировать.
Например, если вы хотите добавить метод "DoSomething()" к объекту System.Windows.Forms, так как у вас нет доступа к этому коду, вы просто создадите метод расширения для формы с помощью следующий синтаксис.
Public Module MyExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Sub DoSomething(ByVal source As System.Windows.Forms.Form)
'Do Something
End Sub
End Module
Теперь в форме вы можете вызвать "Me.DoSomething()".
Таким образом, это способ добавить функциональность к существующим объектам без наследования.
Метод расширения - это "трюк компилятора", который позволяет имитировать добавление методов в другой класс, даже если у вас нет исходного кода для него.
Например:
using System.Collections;
public static class TypeExtensions
{
/// <summary>
/// Gets a value that indicates whether or not the collection is empty.
/// </summary>
public static bool IsEmpty(this CollectionBase item)
{
return item.Count == 0;
}
}
В теории все классы коллекции теперь включают метод IsEmpty
, который возвращает true, если метод не имеет элементов (при условии, что вы включили пространство имен, которое определяет класс выше).
Если я пропустил что-нибудь важное, я уверен, что кто-то это укажет. (Пожалуйста!)
Естественно, что существуют правила об объявлении методов расширения (они должны быть статическими, первый параметр должен предшествовать ключевому слову this
и т.д.).
Методы расширения фактически не изменяют классы, которые они, по-видимому, расширяют; вместо этого компилятор управляет вызовом функции для правильного вызова метода во время выполнения. Тем не менее, методы расширения должным образом отображаются в раскрывающихся списках intellisense с отличительным значком, и вы можете документировать их так же, как и обычный метод (как показано выше).
Примечание. Метод расширения никогда не заменяет метод, если метод уже существует с той же сигнатурой.
Вот пример в VB.Net; обратите внимание на атрибут Extension(). Поместите это в модуль в свой проект.
Imports System.Runtime.CompilerServices
<Extension()> _
Public Function IsValidEmailAddress(ByVal s As String) As Boolean
If String.IsNullOrEmpty(s) Then Return False
Return Regex.IsMatch(email, _
"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$")
End Function
Этот вопрос уже был дан ответ, но я хотел бы добавить, что это очень полезно, если у вас есть типы, которые находятся в другом проекте, и вы не хотите возвращаться к этому проекту, чтобы добавить некоторые функциональность. Мы используем NHibernate и имеем проект для нашего уровня сохранения данных, который ребята хотят сохранить в чистоте. Чтобы получить хорошие и открываемые дополнительные методы на этом объекте, я смог использовать методы расширения, и это действительно осветил мой день.
Кроме того, поскольку никто другой не разместил его, вот хорошая статья об этом на MSDN - http://msdn.microsoft.com/en-us/library/bb383977.aspx
Я думал, что добавлю объяснение, более концептуальное и менее зависимое от кода.
Представьте, что Форд откатывается от строительной линии. У вас нет доступа к строительной линии, но вы хотите, чтобы все автомобили Ford могли иметь дополнительный спойлер, добавленный в заднюю часть автомобиля (выглядит более прохладно, когда на дисплее). Как ты собираешься это сделать? В мире вычислений, если у вас нет доступа к исходной строительной линии внутри Ford factory, вы не можете просто болтать вещи с Ford. Теперь вы можете: использовать методы расширения.
Теперь вы можете делать такие вещи:
Ford hilux = new Ford();
hilux.DisplayRearFoiler(); // you can now do this even though you don't have access to the Ford source code.
Вам нужно будет создать метод расширения. Обратитесь к приведенным выше ответам.
Я хочу ответить на методы расширения в терминах Sealed class.
Предположим, что у вас есть Sealed Class, который содержит жизненно важные методы. Теперь вы хотите добавить к нему новый метод. Предположим, что этот класс входит во внешнюю DLL, поэтому вы не можете добавить к нему новый метод. Что ты будешь делать?
Возьмем другой пример. Предположим, что класс встроен в ваше приложение вашим Менеджером проектов или Гуру безопасности. Вы можете отредактировать этот класс только с разрешения вашего Менеджера проектов или Гуру безопасности.
Вы можете решить удалить Sealed Keyword из этого класса и наследует его в другом классе. Затем внутри подкласса (который наследует этот класс) вы можете добавить свой новый метод.
Но Wait → Вы не можете просто удалить Sealed Keyword, поскольку это может поставить под угрозу безопасность всего приложения. Могу поспорить, что ваш премьер-министр или Гуру безопасности никогда не предоставят вам такое разрешение, ссылаясь на проблемы безопасности.
Так что можно сделать здесь?
Ответ Методы расширения, который можно добавить в статическом классе, и вам даже не нужно прикасаться к закрытому классу.
Пример: -
sealed class MyData
{
private double D1, D2, D3;
public MyData(double d1, double d2, double d3)
{ D1 = d1; D2 = d2; D3 = d3; }
public double Sum() { return D1 + D2 + D3; }
}
static class ExtendMyData
{
public static double Average(this MyData md)
{
return md.Sum() / 3;
}
}
Я добавил публичный статический метод с именем Среднее в новый статический класс. Этот метод имеет параметр основного класса с ключевым словом 'this'.
Теперь, чтобы вызвать метод Average, я использую объект родительского закрытого класса, а не подкласс.
MyData md = new MyData(3, 4, 5);
double exAverage = md.Average();
Надеемся, что вы найдете полезные методы расширения.
Метод расширения в С#
Что такое метод расширения?
Extension method means Class name and method name are having with Static Key word.
Метод расширения, использующий ключевое слово "this" и должен быть первым идентификатором упоминания, этот тип должен быть одинаковым для like,
публичная статическая строка Meth (эта строка i, int j)
а также
string res = "ae".Meth(num);
Жирная часть является идентификационным адресом. Пространство имен должно быть таким же.
Зачем нам нужно расширение?
Мы используем одну и ту же функцию во многих местах, после не смог найти, почему мы используем здесь. По этой причине используется адресная идентификация. Статический означает один экземпляр. Это может получить доступ только к статической функции-члену. Даже как получить доступ без статических методов класса в статическом классе? Пример: см. Ошибка метания в методе "Sal",
статический класс Emp {public int Sal (int i, int j) {return я * j; } } }}
Доступ только к статическому члену. А также
введите описание изображения здесь
В следующем коде мы не можем создать объект для нестатического класса в статическом классе. Тогда как получить доступ к нестатическому методу в статический класс. По этой причине мы придерживаемся метода Extension без наследования.
Например, добавить или даже функциональность, используя метод расширения здесь,
используя систему. Текст;
использование System.Threading.Tasks;
namespace Extension_Method {статический класс Program {
public static string Meth (this string i,int j)
{
if (j % 2 == 0)
{
return "Even";
}
else
{
return "ODD";
}
}
}
class program2
{
static void Main (string [] args)
{
Console. WriteLine ("Enter Integer");
int num = Convert.ToInt32(Console.ReadLine());
string res = "ae".Meth(num);
Console. WriteLine(res);
Console.ReadLine();
}
}
Результат:
Иногда мы хотим добавить наши собственные дополнительные функции к типу и использовать их как обычные методы экземпляра для этого типа. Если бы у нас был исходный код, мы могли бы легко добавить новую функциональность без создания методов расширения. Но проблема возникает, когда у нас нет исходного кода и мы все еще хотим добавить и вызвать дополнительные функции как методы экземпляра для типа; Методы расширения служат для этой цели добавления наших собственных функциональных возможностей к типу и использования их в качестве методов экземпляра для типа, когда исходный код недоступен.
Когда мы хотим добавить нашу собственную функциональность, мы можем даже создать отдельный статический класс и вызывать его статические методы в нашем коде вместо того, чтобы создавать методы расширения, но проблемой с этим может быть читаемость кода.
LINQ значительно выигрывает от методов расширения.
Они могут быть действительно полезны во время разработки, когда необходимые методы легко доступны с помощью Intellisense для нескольких разработчиков; в то время как со статическими методами мы должны будем писать className.MethodName() каждый раз в нашем коде.
Метод расширения - это метод, с помощью которого мы можем добавить метод к существующему типу данных. Ниже приведен пример того, как мы можем добавить методы к существующему типу данных.
Код:
public static class ExtensionMethods
{
public static int WordCount(this string str)
{
return str.Split(' ').Count();
}
public static int LongestWord(this string str)
{
return str.Split(' ').Select(x =>
x.Length).OrderByDescending(y =>
y).FirstOrDefault();
}
}
Код:
public static void Main(String[] args)
{
string str = "this is my name punit";
int i = str.LongestWord();
}
Ключевые моменты:
класс метода расширения должен быть статическим
у первого аргумента метода расширения будет это ключевое слово, и этот метод также должен быть статическим