Дополнительные методы по сравнению с наследованием

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

Спасибо!

42
задан Matt 19 November 2019 в 08:45
поделиться

6 ответов

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

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

33
ответ дан 26 November 2019 в 23:49
поделиться

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

Например, методы расширения Skip и Take .

14
ответ дан 26 November 2019 в 23:49
поделиться

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

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

Еще одно отличное место для методов расширения - против перечислений. Я почти всегда включаю метод расширения HasFlag в любые создаваемые мной перечисления [Flags] .

8
ответ дан 26 November 2019 в 23:49
поделиться

Они очень разные, например, стандартные операторы запросов LINQ являются отличным примером методов расширения, которые должно быть сложно реализовать с помощью наследования, но если у вас есть доступ к классу и вы можете изменить источник, это будет лучше использовать наследование,
РЕДАКТИРОВАТЬ
и вот некоторые правила, которые я нахожу здесь Возможности C # 3.0: Методы расширения

  • Методы расширения не могут использоваться для переопределения существующих методов
  • Метод расширения с то же имя и подпись, что и у метода экземпляра, не будут вызываться
  • Концепция методов расширения не может применяться к полям, свойствам или событиям
  • Используйте методы расширения экономно .... чрезмерное использование может быть плохой вещью!
2
ответ дан 26 November 2019 в 23:49
поделиться

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

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

Например:

string a = null;
return a.IfNullOrEmpty("Default Value");

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

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

2
ответ дан 26 November 2019 в 23:49
поделиться

По возможности используйте наследование вместо методов расширения .

edit

] Я предпочитаю, чтобы это было коротким и простым, но я, конечно, отвечу на дополнительные вопросы.

В случаях, когда возможно наследование, то есть классы, которые не запечатаны, это почти всегда лучший вариант, чем методы расширения. Фактически, это то, что говорится в документе с лучшими практиками , на который ссылается womp. В нем есть такие заголовки, как «Остерегайтесь методов расширения», «Подумайте дважды, прежде чем расширять типы, которыми вы не владеете» и «Предпочитайте расширения интерфейса расширениям классов». Другими словами, он просто говорит о том, что сделал мой однострочный, более подробно.

В статье действительно приводятся подробные причины, но суть в том, что именно так были разработаны методы расширения. Они были добавлены к языку в конце игры в качестве синтаксического сахара, чтобы позволить MS вклиниваться в LINQ без необходимости возвращаться и изобретать велосипед. Это канонический пример того, для чего они нужны. Еще один хороший пример - добавление служебных методов, таких как:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }

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

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

Они были добавлены к языку в конце игры как немного синтаксического сахара, чтобы позволить MS вклиниваться в LINQ без необходимости возвращаться и изобретать колесо. Это канонический пример того, для чего они нужны. Еще один хороший пример - добавление служебных методов, таких как:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }

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

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

Они были добавлены к языку в конце игры в качестве синтаксического сахара, чтобы позволить MS вклиниваться в LINQ без необходимости возвращаться и изобретать велосипед. Это канонический пример того, для чего они нужны. Еще один хороший пример - добавление служебных методов, таких как:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }

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

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

Это канонический пример того, для чего они нужны. Еще один хороший пример - добавление служебных методов, таких как:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }

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

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

Это канонический пример того, для чего они нужны. Еще один хороший пример - добавление служебных методов, таких как:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }

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

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

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

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

8
ответ дан 26 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: