Что такое методы расширения? - PullRequest
41 голосов
/ 31 декабря 2008

Что такое методы расширения в .NET?



EDIT: Я разместил следующий вопрос на Использование методов расширения

Ответы [ 10 ]

55 голосов
/ 31 декабря 2008

Методы расширения позволяют разработчикам добавлять новые методы в общедоступные контракт существующего типа CLR, без необходимости подкласса или перекомпилируйте исходный тип.

Методы расширения помогают смешать гибкость поддержки "Duck Typing" популярный в динамических языках сегодня с производительностью и временем компиляции проверка строго типизированного языки.

Ссылка: 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-\.]+@([\w-]+\.)+[\w-]{2,4}$");
    return regex.IsMatch(s);
}

Теперь вышеприведенный метод может быть вызван напрямую из любой строки, например:

bool isValid = "so@mmas.com".IsValidEmailAddress();

Добавленные методы также появятся в IntelliSense:

alt text
(источник: 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 class:

Extended ex = new Extended();

Console.WriteLine(ex.average());

Ссылка: http://aspguy.wordpress.com/2008/07/03/a-practical-use-of-serialization-and-extension-methods-in-c-30/

11 голосов
/ 22 апреля 2016

Методы расширения - простое объяснение

Предположим, у меня есть собака. Все собаки - все животные типа собаки - делают определенные вещи:

  1. Ешь
  2. WagsTail
  3. Крики «Гав!»
  4. Shakes Paw и т. Д.

То, что может делать собака, называется «методами».

Теперь давайте предположим, что Великий Программист в 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();

Вы можете добавить метод в класс , не имея исходного кода . Это может быть очень удобно!

6 голосов
/ 31 декабря 2008

Методы расширения позволяют разработчикам "добавлять" методы к объектам, которыми они не могут управлять.

Например, если вы хотите добавить метод «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 ()».

Таким образом, это способ добавить функциональность к существующим объектам без наследования.

5 голосов
/ 31 декабря 2008

Метод расширения - это «трюк компилятора», который позволяет имитировать добавление методов в другой класс, даже если у вас нет исходного кода для него.

Например:

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 с отличительным значком, и вы можете задокументировать их так же, как и обычный метод (как показано выше).

Примечание: Метод расширения никогда заменяет метод, если метод уже существует с такой же сигнатурой.

1 голос
/ 31 декабря 2008

Вот пример в 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
0 голосов
/ 29 декабря 2018

Иногда мы хотим добавить наши собственные дополнительные функции к типу и использовать их как обычные методы экземпляра для этого типа. Если бы у нас был исходный код, мы могли бы легко добавить новую функциональность без создания методов расширения. Но проблема возникает, когда у нас нет исходного кода и мы все еще хотим добавить и вызвать дополнительные функции как методы экземпляра для типа; методы расширения служат для добавления наших собственных функций в тип и использования их в качестве методов экземпляра для типа, когда исходный код недоступен.

Когда мы хотим добавить нашу собственную функциональность, мы можем даже создать отдельный статический класс и вызывать его статические методы в нашем коде вместо создания методов расширения, но проблема с этим может быть кодом читаемость .

LINQ значительно выигрывает от методов расширения.

Они могут быть действительно полезны во время разработки, когда необходимые методы легко доступны с помощью Intellisense для нескольких разработчиков; в то время как со статическими методами мы должны будем писать className.MethodName () каждый раз в нашем коде.

0 голосов
/ 09 апреля 2018

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

Что такое метод расширения?

Extension method means Class name and method name are having with Static Key word.

Метод расширения, использующий ключевое слово «this» и должен быть первой подписью с указанием идентифицирующего адреса, этот тип должен быть таким же, как * 1008

открытая статическая строка Meth ( эта строка i, int j)

и

string res = "ae" .Meth (num);

Жирная часть является идентификационным адресом. Пространство имен должно быть таким же.

Зачем нам нужно расширение?

Мы используем одну и ту же функцию во многих местах, после не смогли найти, почему мы здесь используем. По этой причине используется адресная идентификация. Статический означает один экземпляр. Это может получить доступ только к статической функции-члену. Даже как получить доступ без статических методов класса в статическом классе? Пример: см. Ошибка метания в методе «Sal»,

статический класс Emp { public int Sal (int i, int j) { вернуть я * J; } }

Доступ только к статическому члену. И

введите описание изображения здесь

В следующем коде мы не можем создать объект для нестатического класса в статическом классе. Тогда как получить доступ к нестатическому методу в статический класс. По этой причине мы придерживаемся метода Extension без наследования.

Например, функция добавления или выравнивания с использованием метода Extension здесь,

с использованием системы. Текст;

с использованием System.Threading.Tasks;

namespace Extension_Method { Программа статического класса {

    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();
    }
}

Результат:

введите описание изображения здесь

0 голосов
/ 02 июля 2017

Я хочу ответить на Методы расширения в терминах Запечатанный класс .

Предположим, у вас есть Запечатанный класс , содержащий жизненно важные методы. Теперь вы хотите добавить новый метод к нему. Предположим, этот класс входит во внешнюю DLL, поэтому вы не можете добавить в него новый метод. Что ты будешь делать ?

Возьмите другой пример. Предположим, что класс встроен в ваше приложение вашим менеджером проектов или гуру безопасности. Вы можете редактировать этот класс только с разрешения вашего менеджера проекта или гуру безопасности.

Возможно, вы решили удалить запечатанное ключевое слово из этого класса и унаследуйте это в другом классе. Затем внутри подкласса (который наследует этот класс) вы можете добавить свой новый метод.

Но подождите -> Вы не можете просто удалить запечатанное ключевое слово, так как это может поставить под угрозу безопасность всего приложения. Могу поспорить, что ваш премьер-министр или гуру безопасности никогда не даст вам такого разрешения, ссылаясь на проблемы безопасности.

Так что здесь можно сделать?

Ответ: Методы расширения , которые можно добавить в статический класс, и вам даже не нужно больше трогать запечатанный класс.

Пример: -

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();

Надеюсь, вы найдете полезными методы расширения.

0 голосов
/ 12 ноября 2016

Я подумал, что добавлю объяснение, более концептуальное и менее зависимое от кода.

Представьте себе, как «Форд» сходит с конвейера. У вас нет доступа к строительной линии, но вы хотите, чтобы на всех автомобилях Ford был добавлен дополнительный спойлер на заднюю часть автомобиля (на дисплее он выглядит круче). Как ты собираешься это сделать? В мире вычислительной техники, если у вас нет доступа к оригинальной линии строительства на заводе Ford, вы не можете просто прикрутить вещи к Ford. Ну, теперь вы можете: ENTER методы расширения.

Теперь вы можете делать такие вещи:

Ford hilux = new Ford();

hilux.DisplayRearFoiler(); // you can now do this even though you don't have access to the Ford source code.

Вам нужно будет создать метод расширения. Обратитесь к ответам выше.

0 голосов
/ 11 февраля 2011

На этот вопрос уже дан ответ, но я хотел бы добавить, что это очень полезно, если у вас есть типы, которые находятся в другом проекте, и вы не хотите возвращаться к этому проекту, чтобы добавить некоторые функциональность. Мы используем NHibernate и имеем проект для нашего уровня сохраняемости данных, который ребята хотят поддерживать в чистоте. Чтобы получить приятные и обнаруживаемые дополнительные методы для этого объекта, я смог использовать методы расширения, и это действительно осветило мой день.

Кроме того, поскольку никто другой не опубликовал это, вот хорошая статья об этом в MSDN - http://msdn.microsoft.com/en-us/library/bb383977.aspx

...