Qual è il ragionamento alla base della convenzione di denominazione del prefisso "I" per le interfacce in .NET?


10

So che la convenzione "I" esiste da COM, ma non ho mai capito perché non sia stata riconsiderata come ogni altra convenzione di denominazione prima di .NET.

Per quanto riguarda i consumi, l'unica cosa che separa un'interfaccia, per esempio, da una classe astratta, è che possono essere moltiplicati ereditati. Ma tutto dopo Visual Studio 2003 ha mostrato le firme dei tipi nelle descrizioni dei comandi, quindi è inutile come tutte le altre notazioni ungheresi che sono state scartate.

Ho anche pensato che potrebbe essere così che tu possa avere un'implementazione di base dell'interfaccia con lo stesso nome, ad esempio Messageereditare IMessage, ma la maggior parte delle librerie .NET sono andate per aggiungere la parola "Base" alla fine (ad esempio System.Collections.ReadOnlyCollectionBase) invece - e questo ha più senso semantico.

L'interoperabilità COM sembra essere un'altra possibile ragione, ma non è che le classi wrapper che genera siano .NET perfettamente idiomatiche, quindi dubito che sia stata una considerazione estetica.

In uno dei miei progetti più recenti ho completamente dimenticato la convention e mi sento bene. C'è qualcosa che mi manca?


1
Non erediti le interfacce per soddisfarle, grande differenza.
Daniel Little,

Sembra anche una preferenza come IList e List rispetto a List e ArrayList. Probabilmente l'hanno fatto perché IList non è un ListBase ma in realtà è un ListInterface (non un elenco di tipi di interfaccia), se capisci cosa intendo.
Daniel Little,

@Lavinski In .NET IListè un termine generale per una raccolta sequenziale, contigua, accesso casuale, mentre Listè una sequenza, contigua, accesso casuale, raccolta crescente . Credo F # aveva ragione in aliasing Lista ResizeArray; questo è sicuramente un nome molto più descrittivo. IListallora avrebbe potuto essere List, quindi non sembra che sarebbe una ragione neanche.
Rei Miyasaka,

2
IBaseBall e IBaseBallBase hanno più senso per me di BaseBallBase e BaseBallBaseBase (esempio sciocco, lo so: D)
e-MEE,

@ e-MEE altrettanto sciocco sarebbe IIRC, che potrebbe essere un'interfaccia per il protocollo di chat IRC, o l'acronimo di "se ricordo bene".
Rei Miyasaka,

Risposte:


12

Penso che questo potrebbe essere l'unico caso in cui i prefissi sono utili.

Le classi e le interfacce hanno davvero una semantica diversa e, poiché entrambi sono tipi, sono facili da confondere.
Quando vedo una dichiarazione di classe, posso immediatamente dire da cosa deriva e cosa implementa :

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

Sarebbe più difficile capire se la definizione fosse simile

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

E come chiameresti ListClass? Chiaramente non è solo ListBaseperché è utilizzabile da solo.
Quindi, o dobbiamo risolvere un problema che abbiamo appena inventato o adattare un prefisso che separa le classi dalle interfacce, che è ciò che hanno fatto i progettisti di .NET Framework.

Inoltre, personalmente lo trovo utile quando posso dire dalla firma del metodo che funziona con le interfacce.

public void PrintLines (IEnumerable<string> source)

È come un segnale per la mia testa: ehi, posso implementarlo! Posso alimentare il metodo qualunque sia il contratto.

Ovviamente si può sostenere che non è così importante, ma questa è una di quelle piccole cose che valgono il prefisso per me. È particolarmente utile quando si scrive molto codice con i contenitori IoC quando si lavora costantemente con le interfacce e si deve facilmente distinguere tra i due.

A proposito, non solo le interfacce hanno prefissi nel sistema di tipo .NET. Non dimenticare i parametri di tipo generico:

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

Questa è un'altra situazione in cui è estremamente utile poter distinguere tra classi e un altro tipo di tipi.


2
Puoi facilmente capire che sapendo che "la prima classe è eredità, la seconda e la successiva sono interfacce".
Saeed Neamati,

3
Sembra una ragione plausibile. Java sembra aver risolto un po 'più bene, semplicemente utilizzando le parole chiave per chiarire la lista: class Dog extends Mammal implements MailmanChaser. @Saeed puoi avere una classe che non eredita da nulla, quindi il primo tipo nella lista è in realtà un'interfaccia piuttosto che una classe base.
Rei Miyasaka,

+1 per la parte in grassetto, anche se posso pensare a un altro posto in cui una convenzione basata su prefissi sarebbe stata utile: distinguere tra un campo che incapsula la proprietà esclusiva di un int[](o altro oggetto di tipo mutabile) che può mutare ma non condividere, e uno che incapsula la proprietà condivisa di un int[]che, sebbene il suo tipo consentirebbe la mutazione, a nessuno è permesso di mutare.
supercat

6

Non credo che ti manchi nulla, è solo un'abitudine storica.

Sono d'accordo anche con te e ho anche lasciato cadere l'io su un paio di progetti medio-piccoli senza alcun effetto negativo.


2
La cosa strana però è che hanno praticamente buttato via ogni altra convenzione obsoleta tranne questa. Neanche la storia lo spiega. Sento ancora che ci deve essere stata una ragione, a meno che non sia stata solo una politica interna - ma anche in quel momento, non riesco proprio a vedere una ragione per cui qualcuno si arrabbierebbe per il fatto che io venissi lasciato cadere.
Rei Miyasaka,

2

Penso che l'unico motivo, secondo le Naming Guidelines di Microsoft su interfacce e classi , sia che, a volte, ci sono conflitti tra il nome dell'interfaccia e la classe che lo implementa. Ciò risale al fatto che le interfacce sono in realtà lo scheletro, non la carne, e la classe implementatrice è in realtà la carne (realizzando il progetto). Pertanto, IAnimal sta solo descrivendo ciò che un animale dovrebbe avere , mentre Animal può dirti quello che ha .

Tuttavia, personalmente sono completamente d'accordo con te sul fatto che potremmo semplicemente usare Animal Base per l'interfaccia e Animal per la classe.

D'altra parte, a volte due cose sono così contrastanti che una squadra decide di organizzare una convenzione per prevenire ulteriori conflitti, nonostante le decisioni già prese. Ad esempio, in ASP.NET MVC, sia le viste parziali che i layout (pagine master) sono esattamente come una vista normale , mentre offrono funzionalità diverse. Pertanto Microsoft, nonostante enfatizzi di non utilizzare il carattere di sottolineatura nella denominazione, suggerisce di sottolineare Layout e Viste parziali con un carattere di sottolineatura.


Cosa c'è che non va AnimalInterfaceinvece AnimalBase? Non è una classe di base, è un'interfaccia.
Scott Whitlock,

3
ma cosa c'è di sbagliato in IAnimal invece di AnimalInterface? sicuramente siamo andati fino al punto di partenza, il che dimostra che alcune delle notazioni ungheresi erano utili. Buttarli tutti fuori (tranne per I e T) è stato più un po 'più complicato che un tentativo premuroso di trovare un sistema migliore.
gbjbaanb,

2
@ScottWhitlock: per me IAnimalè molto più leggibile di AnimalInterface. I nomi dettagliati sono preferibili, tranne nei casi in cui una semplice breve convenzione può essere utilizzata per qualcosa che si verifica abbastanza frequentemente. E le interfacce sono un caso del genere.
maaartinus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.