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

Почему имена префикса С# с именем "I"

В чем смысл этого соглашения об именах?

Я не вижу никакой пользы. Дополнительный префикс просто загрязняет API.

Мое мышление встроено в Konrad ответ на этот связанный question; выбранный , о котором я в основном прошу здесь.

4b9b3361

Ответ 1

В полной противоположности, соглашение об именах четко идентифицирует интерфейс.

Например, если у вас есть:

public class Dog : IPet, IMammal
{
    ....

Просто прочитав его, я могу с уверенностью предположить, что IPet и IMammal - это, вероятно, интерфейсы.

CLR.NET допускает наследование одного класса. Итак, если у меня есть базовый класс... Я могу наследовать только один класс из него. Позволяет изменить интерфейс IPet на базовый класс. Наш пример теперь становится

public class Dog : Pet, IMammal
{
    ....

Я наследую класс Pet и реализую интерфейс IMammal.

Если бы мы сделали то, что вы предлагаете и удалили букву "Я", мы имеем следующее:

public class Dog : Pet, Mammal
{
    ....

Какой из классов я наследую? Какой интерфейс я реализую? Это сбивает с толку? (FYI.. вы должны сначала поставить базовый класс, поэтому вы можете утверждать, что точка... но если вы утверждаете, что я удаляю букву я из префикса имен интерфейсов, я сомневаюсь, что вы тоже следуете этой практике)

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

Ответ 2

Мне также нравится, что я могу читать его как "Я глагол-поведение", как в "ICanSave" или "IDoDoubleEntry" и т.д.

Ответ 3

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

Тем не менее, я все еще использую его, потому что в этом случае IInterface рекомендуется Microsoft, а "стандарт лучше, чем лучше".

Ответ 4

На самом деле, мне полезно избегать именования столкновений, я мог бы, например, создать конкретный класс Fred, который реализует IFred

Ответ 5

Почему это не функция синтаксического выделения вместо венгерской нотации? Почему среда IDE просто выделяет курсивом идентификаторы, относящиеся к интерфейсам, если это так важно различать классы и интерфейсы. Я ненавижу "или" m "перед полями," C" перед классами и т.д. Еще хуже то, что программисты пишут очень плохие API, например:

public class List : IList

вместо более разумного:

public class LinkedList : List
public class ArrayList : List
public class HashList : List

Даже авторы обычного класса .NET попали в эту ловушку. Имя класса НИКОГДА не должно быть именем интерфейса с удаленным "I". Имя класса всегда должно указывать пользователю, как класс отличается от других возможных реализаций интерфейса (ов). Я голосую за то, что выбрал глупое "я" по этой причине.

Кроме того, когда я использую intellisense, я хочу группировать вещи по функциональной области, а не по классу или интерфейсу. Я никогда не думаю, что "мне нужен интерфейс, а не класс". Я всегда думаю: "Мне нужно что-то, что делает X".

Ответ 6

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

class Dog: IBark

Это не работает для структурных интерфейсов, таких как интерфейсы WCF, но нам не нужно все время развлекаться.

чтобы ответить на ваш вопрос, подумайте о I как "реализует" Итак...

class DogDataService : Dog, IDataService

этот класс службы наследует от Dog и реализует IDataService

Я по-прежнему не отвечаю на ваш вопрос, но I полезен, потому что вы получаете именование коллизий между пространством имен, классом и интерфейсом.

namespace DataService
interface DataService
class DataService: DataService

поэтому мы получаем

namespace DataServices
interface IDataService
class DataService : IDataService

Я думаю, что на самом деле это соглашение о здравомыслии.

Ответ 7

Если вы считаете два "наилучших практических афоризма"

Ясность королева

и

шум плох

между ними существует конфликт. Вопрос в том, когда возникает ясность?

Для меня это более шумно (но не менее ясно) писать Person person = new PersonImpl() чем IPerson person = new Person().

Ответ 8

Это либо то, либо добавить "Impl" к реализации интерфейса (argh). У меня нет проблемы с "я", это простое и простое именование для интерфейса.

Ответ 9

Он легко идентифицируется как интерфейс.

Ответ 10

Соглашение "I", похоже, является старым соглашением, которое сегодня не будет актуальным. Текущий редактор кода предоставляет много информации о типе, который вы используете, поэтому утверждая, что проще идентифицировать интерфейс, это просить, чтобы пространство имен было префиксом "N", потому что вы хотите быть уверенным, что вы не будете его смешивать с конкретный класс (префикс с "C"?).

Соглашение не означает, что это хорошее соглашение. Иногда, это просто потому, что люди используют его...

Возьмем, к примеру, генератор документации С#: он не заботится об этом... если ваш интерфейс не имеет префикса с "я", вы все равно увидите свой интерфейс в части интерфейса вашей документации. Вы действительно думаете, что наличие префикса "I" для всех ваших интерфейсов в разделе интерфейса вашей документации является релевантной информацией и поможет вам лучше идентифицировать интерфейсы?

Ответ 11

Соглашения об именах дают вам возможность сообщить вам что-то об объекте, прежде чем использовать его. Соглашения об именах широко используются в течение многих лет, полностью возвращаясь к требованию fortran о том, что целочисленные значения были ограничены (если я правильно помню) именам переменных, таких как "i" и "j".

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

Префиксные имена интерфейсов с я - относительно низкий, безвредный способ идентификации этого объекта.

Ответ 12

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

У класса должна быть одна причина существования. В базовом классе никогда не требуется устанавливать второстепенные роли. Например:.

public class XmlConfigurationFile : ConfigurationFile, IDisposable
{
}

public class YamlConfigurationFile : ConfigurationFile, IDisposable
{
}

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

Покончить с этим:

public class XmlConfigurationFile : IDisposable, ConfigurationFile
{
}

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

Проблема начинается, когда вы создаете классы с несколькими причинами существования:

public class MyConfigurationFile : XmlConfigurationFile, YamlConfigurationFile
{
}

Даже если XmlConfigurationFile и YamlConfigurationFile были бы интерфейсами, это все еще указывает на плохой дизайн. Как ваш файл конфигурации может быть Xml и Yaml одновременно?

Если вы читаете приведенные примеры (здесь и в других местах), люди всегда стараются найти хороший пример того, когда имеет значение I-префикс. Один из ответов здесь:

public class Dog : Pet, Mammal
{
}

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

public class Dog : Mammal, Pet
{
}

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

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

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

Ответ 13

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

Ответ 14

Во-первых, я считаю, что префикс с описанием я неверен, потому что это означает, что реализация может иметь более короткое имя. IList (intf) → Список. Это анти-шаблон, как мы все знаем, мы должны использовать intf и, возможно, только конкретные типы при создании. Не плачьте мне, это обобщение, но предпосылка является intf only impl редко. Имя реализации должно описывать, как он реализует intf или что он делает. Think intf List, LinkedList, который реализует List, используя связанный список. Кто заботится, если это длиннее, поскольку мы должны использовать List больше всего времени. Если у нас есть класс, реализующий много intf, мы, вероятно, не должны включать все intf в качестве теней в реальную цель класса. В случае, если что-то, что удаляется без intf, имеет смысл. Например, ppl назовите меня по имени не Person, Sibling, разработчик и т.д., Используя мое имя, это самое лучшее описательное имя. Я полагаю, что если класс - это простой intf, тогда назовем его Default Intf, что делает его более важным - это реализация Intf по умолчанию. Имена классов. В конце концов, это должно быть понятным для человека и почти короткой фразой, описывающей их цель. Префиксные коды и т.д. Невелики, поскольку мы обмениваемся словами не кодами. Компьютеры не относятся к классам, поэтому почему остается то, что мы называем вещи так, чтобы имена помогали нам и нашим коллегам.

Ответ 15

Мне кажется традиционная конвенция от венгерской нотации. "Принципы именования интерфейсов" говорит "имена интерфейса префикса с буквой I, чтобы указать, что тип является интерфейсом". Руководство по дизайну каркаса также говорит: "Идентифицировать имена интерфейса префикса DO буквой I, чтобы указать, что тип является интерфейсом".

Это просто соглашение о кодировании, поэтому трудно определить хорошее или плохое. Важные вещи - это последовательность.

Ответ 16

TL; DR

Для меня двойное соглашение класса Foo реализации IFoo (особенно если оба находятся в одной сборке) передает конкретное намерение, что:

  • Связывание с зависимостью от Foo должно всегда быть косвенным через соответствующий интерфейс IFoo (и, вероятно, быть введенным через контейнер IoC)
  • Первоначальная конструкция IFoo является запатентованным интерфейсом без повторного использования, специально предназначенным для того, чтобы позволить классам, зависящим от Foo, отмахиваться от этой зависимости во время модульного тестирования.
  • Помимо вышеизложенного, читателю не нужно выводить дополнительный интеллект в дизайн интерфейса IFoo
  • И наоборот, если в более поздней точке требуется несколько конкретных классов реализации IFoo, то в иерархию должна быть доработана правильная конструкция разделения сегрегации.

Обоснование

Для того, чтобы иметь возможность Mock или Stub из класса, широко распространенная передовая практика в Unit Testing заключается в развязывании зависимостей между классами только через интерфейсы. Эта развязка интерфейса также будет выполняться для классов, в противном случае никогда не было требований к дизайну для полиморфизма (т.е. Существовала бы только одна такая реализация, если бы не необходимость модульное тестирование).

Как следствие, рефакторинг и повторное использование этих интерфейсов (например, Принцип разделения цепей SOLID) не применяется к таким "макетируемым" интерфейсам - часто существует соотношение 1:1 между общедоступными методами, свойствами и событиями "mockable" класса (Foo) и его развязанным интерфейсом IFoo (аналогично COM-эре автоматические интерфейсы в VB).

Инструменты, такие как VS, и Resharper может сделать извлечение таких открытых символов из класса в отдельный интерфейс тривиальным, как задумка.

Кроме того, если мы считаем, что Mocking frameworks, такие как Moq, позволяют определение реализаций интерфейса "на лету" , нам не нужно тратить усилие, называя конкретный класс двойной реализации.

Ответ 17

Скорее всего, это позволит легко идентифицировать его в intellisense, так как все интерфейсы будут сжиматься вместе. Подобно тому, как я префикс всех своих элементов управления пользовательским интерфейсом с помощью btn, tb, lb. Когда intellisense пинает во всем, он объединяется в одну легкую группу.

Ответ 18

Со всеми аргументами о соглашениях об именах и присваивании имен именам и методам, которые фактически описывают, что они делают... почему бы не просто назвать ваши интерфейсы (например, PetInterface, PlayerInterface и т.д.) и удалить префикс "Я" все вместе ". Итак, что вы должны набрать еще 9 букв, по крайней мере," I "удаляется, и мы знаем, что это не класс, потому что он говорит" Интерфейс".