Почему префикс C # имен интерфейсов с «I» - PullRequest
29 голосов
/ 13 января 2009

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

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

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

Ответы [ 18 ]

53 голосов
/ 13 января 2009

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

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

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

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

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

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

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

Если мы сделали то, что вы предлагаете, и удалили букву «Я», у нас есть это:

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

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

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

30 голосов
/ 13 января 2009

Мне также нравится это, потому что я могу прочитать его как «I-поведение глагола», как в «ICanSave» или «IDoDoubleEntry» и т. Д ...

24 голосов
/ 16 января 2009

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

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

13 голосов
/ 12 октября 2010

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

public class List : IList

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

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

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

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

11 голосов
/ 13 января 2009

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

4 голосов
/ 30 октября 2009

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

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

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

4 голосов
/ 23 декабря 2011

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

ясность - король

и

шум плохой

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

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

3 голосов
/ 13 января 2009

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

3 голосов
/ 04 сентября 2010

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

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

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

2 голосов
/ 05 августа 2016

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

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

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» является техническим требованием и не поможет вам лучше рассказать историю вашего приложения.

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

...