Які міркування, що стоять за умовою іменного префікса "I" для інтерфейсів у .NET?


10

Я знаю, що конвенція "Я" існує вже з часів COM, але я ніколи не розумів, чому вона не була переглянута, як і будь-яка інша конвенція про іменування раніше .NET має.

Єдине, що відокремлює інтерфейс від, скажімо, абстрактного класу, - це те, що вони можуть множитися у спадок. Але все після того, як Visual Studio 2003 показав підписи типів у підказках, тому це так само марно, як і всі інші угорські позначення, які були відкинуті.

Я також подумав, що це може бути так, що ви можете мати базову реалізацію інтерфейсу з тим же ім'ям, наприклад, Messageуспадковувати IMessage, але більшість бібліотек .NET пішли на додавання слова "Base" в кінці (наприклад System.Collections.ReadOnlyCollectionBase) замість цього - і це має більш смисловий сенс.

COM interop, здається, є ще однією можливою причиною - але це не так, якби класи, які він створює, абсолютно ідіоматичні. NET, тому я сумніваюся, що це було естетичним аспектом.

В одному з моїх нових проектів я повністю відмовився від конвенції, і це почувається просто чудово. Щось мені не вистачає?


1
Ви не успадковуєте інтерфейси для їх виконання, велика різниця.
— Даніель Літтл

Крім того, схоже на перевагу, як IList та List, на відміну від List та ArrayList. Вони, ймовірно, зробили це тому, що IList - це не ListBase, але насправді це ListInterface (а не інтерфейс списку типів), якщо ви розумієте, що я маю на увазі.
— Даніель Літтл

@Lavinski In .NET IList- це загальний термін для послідовної, суміжної колекції, випадкового доступу, тоді Listяк це послідовний, суміжний, випадковий доступ, зростаюча колекція. Я думаю , що F # було право в альясінге Listдо ResizeArray; це, безумовно, набагато більш описова назва. IListтоді це могло бути List, так що, схоже, це теж не було б причиною.
— Rei Miyasaka

2
IBaseBall і IBaseBallBase має для мене більше сенсу, ніж BaseBallBase і BaseBallBaseBase (дурний приклад, я знаю: D)
— e-MEE

@ e-MEE так само дурним буде IIRC, який може бути інтерфейсом для протоколу чату IRC або абревіатурою "якщо я правильно пам'ятаю".
— Рей Міясака

Відповіді:


12

Я думаю, що це, можливо, єдиний випадок, коли префікси корисні.

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

public sealed class ActivityCollection : List<Activity>, 
    IList<Activity>, ICollection<Activity>, IEnumerable<Activity>, 
    IList, ICollection, IEnumerable

Було б важче зрозуміти, як таке визначення виглядало

public sealed class ActivityCollection : ListClass<Activity>, 
    List<Activity>, Collection<Activity>, Enumerable<Activity>, 
    List, Collection, Enumerable

А як би ти подзвонив ListClass? Зрозуміло, що це не тільки ListBaseтому, що воно є корисним самостійно.
Отже, ми або повинні вирішити проблему, яку ми тільки що винайшли, або адаптувати префікс, який відокремлює класи від інтерфейсів, що і зробили дизайнери .NET Framework.

Також особисто мені здається корисним, коли з підпису методу можу сказати, що він працює з інтерфейсами.

public void PrintLines (IEnumerable<string> source)

Це як сигнал в голову: ага, я можу це реалізувати! Я можу подати метод, що відповідає договору.

Звичайно, можна стверджувати, що це не так важливо, але це одна з тих дрібниць, які роблять префікс вартим для мене. Це особливо корисно при написанні великої кількості коду з контейнерами IoC, коли ви постійно працюєте з інтерфейсами і вам потрібно легко розмежувати їх.

До речі, не тільки в інтерфейсах є префікси в системі типу .NET. Не забувайте про параметри загального типу:

public delegate TResult Func<in T, out TResult>(
    T arg
)

Це ще одна ситуація, коли надзвичайно корисно вміти розмежовувати класи та інші типи.


2
Ви можете легко зрозуміти, що знаючи, що "перший клас - це спадщина, другий клас і далі - це інтерфейси".
— Саїд Неаматі

3
Це здається правдоподібною причиною. Java , здається, вирішив його трохи більш красиво, просто використовуючи ключові слова , щоб уточнити список: class Dog extends Mammal implements MailmanChaser. @Saeed у вас може бути клас, який не успадковує нічого, тому перший тип у списку насправді є інтерфейсом, а не базовим класом.
— Rei Miyasaka

+1 для частини жирного шрифту, хоча я можу придумати ще одне місце, де конвенція на основі префіксу була б корисною: розрізнити поле, яке інкапсулює ексклюзивне право власності на int[](або інший об'єкт змінного типу), яке воно може мутувати, але не share, і той, який інкапсулює спільне право власності на це int[], хоча його тип дозволив би мутувати, нікому не дозволяється мутувати.
— supercat

6

Я не думаю, що вам нічого не вистачає, це лише історична звичка.

Я погоджуюсь і з вами, і також я кинув "Я" на пару малих та середніх проектів без згубного ефекту.


2
Що дивно, що вони викинули практично будь-яку іншу застарілу конвенцію, крім цієї. Історія теж не дуже пояснює це. Я все ще відчуваю, що мала бути причина, якщо тільки це не була просто внутрішня політика - але навіть тоді я не можу побачити причини, щоб хтось засмутився, як мене кинули.
— Rei Miyasaka

2

Я думаю, що згідно з Посібниками з питань іменування Microsoft щодо інтерфейсів та класів , єдиною причиною є те, що іноді виникають конфлікти між назвою інтерфейсу та класом, що реалізує це. Це повертається до того, що інтерфейси - це насправді скелет, а не м'ясо, а клас реалізатора насправді є м'ясом (реалізуючи план). Таким чином, IAnimal описує лише те, що має мати тварина , тоді як Animal може сказати вам, що має .

Однак я особисто повністю з вами погоджуюся з тим, що ми могли просто використовувати Animal Base для інтерфейсу, а Animal - для класу.

З іншого боку, іноді дві речі настільки суперечать один одному, що команда вирішує створити конвенцію для запобігання подальшим конфліктам, незважаючи на вже прийняті рішення. Наприклад, в ASP.NET MVC як часткові перегляди, так і макети (головні сторінки) подібно до звичайного перегляду , хоча вони виконують різні функціональні можливості. Таким чином, Microsoft, незважаючи на те, що не використовувати підкреслення в іменуванні, пропонує підкреслити макети та часткові перегляди за допомогою підкреслення.


Що з цим AnimalInterfaceзамість AnimalBase? Це не базовий клас, це інтерфейс.
— Скотт Вітлок

3
але що не так з IAnimal замість AnimalInterface? впевнені, що ми пройшли всю дорогу туди, де ми почали - що просто показує, що деякі «угорські» позначення були корисні. Викидання їх усіх (крім I і T) було скоріше пікантним, ніж продуманою спробою знайти кращу систему.
— gbjbaanb

2
@ScottWhitlock: Для мене IAnimalнабагато легше читати, ніж AnimalInterface. Довершені імена є кращими, за винятком випадків, коли простий короткий конвент може бути використаний для чогось, що відбувається досить часто. І інтерфейси - це такий випадок.
— maaartinus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.