Які міркування, що стоять за умовою іменного префікса "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.