Когда это возможно, используйте наследование вместо методов расширения .
редактировать
Я предпочитаю быть кратким и простым, но я, конечно, отвечу на дополнительные вопросы.
В тех случаях, когда возможно наследование, то есть классы, которые не запечатаны, это почти всегда лучший вариант, чем методы расширения. Фактически, это то, что говорится в документе о лучших практиках , на который ссылается womp. У него есть такие заголовки, как «Остерегайтесь методов расширения», «Подумайте дважды, прежде чем расширять типы, которые вам не принадлежат» и «Предпочитайте расширения интерфейса над расширениями класса». Другими словами, это просто говорит о том, что сделал мой однострочник, более подробно.
В статье приводятся подробные причины, но суть в том, что именно так были разработаны методы расширения для использования. Они были добавлены в язык в конце игры как немного синтаксического сахара, чтобы позволить MS втиснуться в LINQ, не возвращаясь и не изобретая колесо. Это канонический пример того, для чего они хороши. Еще один хороший пример - добавление служебных методов, таких как:
public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }
Обратите внимание, что в этом случае методы расширения были единственным способом выполнения этой дополнительной функции, поскольку строки запечатаны.
Что касается композиции, а не наследования, то, хотя это трюизм, я не вижу здесь смысла. Используем ли мы методы расширения или наследования, цель состоит в том, чтобы изменить интерфейс, чтобы разрешить другой метод. То, как этот метод реализован, будь то с помощью композиции, обобщений или какой-либо другой техники, является ортогональным.