Каждый раз, когда у вас есть функция, которая "обычно применима" к объекту определенного типа, независимо от его состояния, метод расширения является хорошим выбором.
Например, сегодня я добавил два новых метода расширения в нашу кодовую базу:
public static XElement ToXElement(this XmlElement element) { }
public static XmlElement ToXmlElement(this XElement element) { }
Оба они, вообще говоря, действительны для типов, которые они расширяют, независимо от состояния экземпляра или того, где мы его используем.
Если ваш метод не соответствует этим критериям, его, вероятно, следует переместить в вспомогательный метод ближе к контексту, где конкретный случай всегда верен или легко проверяется.
Например, разработчик недавно назначил этот метод расширения:
public static bool ParseYesNoBool(this string input) { }
Здесь есть две проблемы: во-первых, это будет появляться во всех строках приложения, даже если число строк, которые могут быть кандидатами в этом случае, очень мало. Итак, мы нарушили первое правило, так как оно бесполезно независимо от состояния. Точно так же, но во-вторых, потребитель этой функциональности ограничен одним парсером для одного конкретного соединителя с внешней системой. Поэтому продвижение функциональности, специфичной для реализации, в пространство имен общего пользования не имеет смысла. Это было понижено до вспомогательного метода в анализаторе.
Что касается читабельности и отладки, это просто неверно для разработчика любого разумного уровня квалификации.