Подтвердить что ты не робот

Соглашение об именах С# для методов расширения для интерфейса

Я обычно называю свои интерфейсы С# как IThing. Я создаю класс метода расширения для IThing, но я не знаю, как его назвать. С одной стороны, вызов ThingExtensions, по-видимому, подразумевает, что это класс расширения для некоторого класса Thing вместо интерфейса IThing. Это также делает класс расширения удаленным от интерфейса, который он расширяет, при просмотре файлов в алфавитном порядке. С другой стороны, именовав его IThingExtensions, он выглядит так, как будто это сам интерфейс, а не класс расширения для интерфейса. Что бы вы предложили?

Изменить: не существует класса Thing, который реализует IThing в ответ на некоторые комментарии.

4b9b3361

Ответ 1

Я определенно предпочитаю имя ThingExtensions над IThingExtensions. Причина в том, что для большинства программистов префикс I для типа подразумевает, что он является интерфейсом. Это и очень распространенная модель, и часть Руководства по дизайну .Net.

Добавление префикса I для случая метода расширения нарушает как предположения, так и установленные правила.

Существует также приоритет для этого в в библиотеке базового класса. Большинство методов расширения, доступных для IEnumerable, содержатся в типе Enumerable.

Ответ 2

Я лично использовал бы IThingExtensions.

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

Считая, что факт, что это расширения для любого IThing, делает IThingExtensions наиболее ясным. Если у вас есть класс Thing, вызов этого ThingExtensions может показаться неоднозначным (расширяете ли вы интерфейс или само реализацию?).

Таким образом, структура использует совершенно другой подход. Рамочный подход заключается в использовании класса с именем Thing для расширения IThing. Например, см. Enumerable (расширение IEnumerable) и Queryable (расширение IQueryable). Это также будет очень хорошим вариантом.

Ответ 3

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

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

Конечно, это не универсальное соглашение. См. Здесь: Как вы управляете пространствами имен ваших методов расширения?

Ответ 4

Я бы предпочел поместить его в папку (и пространство имен) под названием Extensions и называть ее IThingExtensions.

Ответ 5

Мне ничего не известно о стандартном соглашении. Я бы использовал либо ThingExtensions, либо ThingInterfaceExtensions. Я бы держался подальше от IThingExtensions, как вы также предлагали.

Ответ 6

Я использовал несколько иной подход и вместо суффикса с Extension отменил стратегию именования для префикса класса, содержащего методы расширения, с помощью Extend; мое обоснование таково:

  • Как указано в Ответ Reed Copsey, очень (очень) редко клиентский код ссылается на содержащийся класс непосредственно, поскольку самой точкой методов расширения является эмулирование эталонных методов, Они не будут видеть классы, поэтому ваш выбор названия именования классов должен иметь незначительное влияние.
  • Классы должны быть static, и поэтому вы никогда не создадите их. Поэтому вы никогда не заканчиваете семантическую странность new ExtendThing() в том, что касается именования.
  • Все ваши классы Extend* визуально группируются с сортировкой альфа файлов.
  • И в отношении вашего вопроса, в частности, нет путаницы префикса имен имен интерфейса; вы можете иметь ExtendThing и ExtendIThing и (IMO) их намерение и цель ясно.

namespace MyCompany.Extensions
{
    public static class ExtendObject { }

    public static class ExtendDateTime { }

    public static class ExtendIEnumerable { }
}