Quel est le raisonnement derrière la convention de dénomination du préfixe «I» pour les interfaces dans .NET?

10

Je sais que la convention «I» existe depuis COM, mais je n'ai jamais compris pourquoi elle n'a pas été reconsidérée comme toutes les autres conventions de dénomination avant .NET.

Du point de vue de la consommation, la seule chose qui sépare une interface, disons, d'une classe abstraite, c'est qu'elles peuvent être multipliées par héritage. Mais tout ce qui après Visual Studio 2003 a montré des signatures de type dans les info-bulles, c'est donc aussi inutile que toutes les autres notations hongroises qui ont été ignorées.

J'ai également pensé que cela pourrait être pour que vous puissiez avoir une implémentation de base de l'interface avec le même nom, par exemple Messagehéritant IMessage, mais la plupart des bibliothèques .NET ont opté pour l'ajout du mot "Base" à la fin (par exemple System.Collections.ReadOnlyCollectionBase) à la place - et cela a plus de sens sémantique.

L'interopérabilité COM semble être une autre raison possible - mais ce n'est pas comme si les classes wrapper qu'il génère étaient parfaitement idiomatiques .NET, donc je doute que c'était une considération esthétique.

Dans l'un de mes projets les plus récents, j'ai complètement abandonné la convention, et cela me semble très bien. Y a-t-il quelque chose qui me manque?

Rei Miyasaka
la source
1
Vous n'héritez pas des interfaces pour les remplir, grande différence.
Daniel Little
Cela semble également être une préférence comme IList et List par opposition à List et ArrayList. Ils l'ont probablement fait car IList n'est pas un ListBase mais est vraiment un ListInterface (pas une List of type interface), si vous comprenez ce que je veux dire.
Daniel Little
@Lavinski Dans .NET IListest un terme général pour une collection séquentielle, contiguë, à accès aléatoire, alors qu'il Lists'agit d'une collection croissante , contiguë, à accès aléatoire, croissante . Je pense que F # avait raison dans l' aliasing Listà ResizeArray; c'est certainement un nom beaucoup plus descriptif. IListcela aurait pu l'être List, donc cela ne semble pas non plus être une raison.
Rei Miyasaka
2
IBaseBall et IBaseBallBase ont plus de sens pour moi que BaseBallBase et BaseBallBaseBase (exemple idiot, je sais: D)
e-MEE
@ e-MEE serait également idiot IIRC, qui pourrait être une interface pour le protocole de chat IRC, ou l'acronyme de "si je me souviens bien".
Rei Miyasaka

Réponses:

12

Je pense que cela pourrait bien être le seul cas où les préfixes sont utiles.

Les classes et les interfaces ont vraiment une sémantique différente, et parce que les deux sont des types, elles sont faciles à mélanger.
Quand je vois une déclaration de classe, je peux dire instantanément de quoi elle dérive et ce qu'elle implémente :

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

Il serait plus difficile de comprendre si la définition ressemblait

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

Et comment appelleriez-vous ListClass? De toute évidence, ce n'est pas seulement ListBaseparce qu'il est utilisable seul.
Ainsi, nous devons soit résoudre un problème que nous venons d'inventer, soit adapter un préfixe qui sépare les classes des interfaces, ce que les concepteurs de .NET Framework ont ​​fait.

Aussi, personnellement, je trouve cela utile quand je peux dire à partir de la signature de la méthode qu'elle fonctionne avec les interfaces.

public void PrintLines (IEnumerable<string> source)

C'est comme un signal à ma tête: hé, je peux implémenter ça! Je peux alimenter la méthode tout ce qui correspond au contrat.

Bien sûr, on peut dire que ce n'est pas si important, mais c'est l'une de ces petites choses qui valent le préfixe pour moi. C'est particulièrement utile lors de l'écriture de beaucoup de code avec des conteneurs IoC lorsque vous travaillez constamment avec des interfaces et devez facilement différencier les deux.

Par ailleurs, non seulement les interfaces ont des préfixes dans le système de type .NET. N'oubliez pas les paramètres de type génériques:

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

C'est une autre situation où il est extrêmement utile de pouvoir faire la différence entre les classes et un autre type de types.

Dan
la source
2
Vous pouvez facilement comprendre qu'en sachant que "la première classe est l'héritage, la deuxième classe et les autres sont des interfaces".
Saeed Neamati
3
Cela semble être une raison plausible. Java semble avoir résolu un peu plus bien en utilisant simplement des mots - clés pour clarifier la liste: class Dog extends Mammal implements MailmanChaser. @Saeed, vous pouvez avoir une classe qui n'hérite de rien, donc le premier type de la liste est en fait une interface plutôt qu'une classe de base.
Rei Miyasaka
+1 pour la partie en gras, bien que je puisse penser à un autre endroit où une convention basée sur un préfixe aurait été utile: faire la distinction entre un champ qui encapsule la propriété exclusive d'un int[](ou d'un autre objet de type mutable) qu'il peut muter mais pas partager, et qui encapsule la propriété partagée d'un int[]qui, même si son type permettrait la mutation, personne n'est autorisé à muter.
supercat
6

Je ne pense pas qu'il vous manque quelque chose, c'est juste une habitude historique.

Je suis également d'accord avec vous et j'ai également abandonné le «je» sur quelques projets de petite à moyenne envergure, sans effet néfaste.

Chris Lee
la source
2
Ce qui est bizarre, c'est qu'ils ont jeté pratiquement toutes les autres conventions obsolètes, sauf celle-ci. L'histoire ne l'explique pas non plus. J'ai toujours l'impression qu'il doit y avoir une raison, à moins que ce ne soit vraiment que de la politique interne - mais même dans ce cas, je ne vois vraiment pas pourquoi quelqu'un se fâcherait que je sois abandonné.
Rei Miyasaka
2

Je pense que la seule raison, selon les directives de dénomination de Microsoft sur les interfaces et les classes , est que, parfois, vous avez des conflits entre le nom de l'interface et la classe qui l'implémente. Cela revient au fait que les interfaces sont en fait le squelette, pas la viande, et la classe de l'implémenteur est en fait la viande (réalisant le plan). Ainsi, IAnimal ne décrit que ce qu'un animal devrait avoir , alors qu'Animal peut vous dire ce qu'il a .

Cependant, je suis personnellement entièrement d'accord avec vous sur le fait que nous pourrions simplement utiliser Animal Base pour l'interface et Animal pour la classe.

D'un autre côté, parfois deux choses sont tellement conflictuelles, qu'une équipe décide de fournir une convention pour éviter de nouveaux conflits, malgré des décisions déjà prises. Par exemple, dans ASP.NET MVC, les vues partielles et les mises en page (pages maîtres) sont comme une vue normale , alors qu'elles servent des fonctionnalités différentes. Ainsi, Microsoft, bien qu'il insiste pour ne pas utiliser de soulignement dans la dénomination, suggère de souligner les mises en page et les vues partielles avec un soulignement.

Saeed Neamati
la source
Quel est le problème avec AnimalInterfaceau lieu de AnimalBase? Ce n'est pas une classe de base, c'est une interface.
Scott Whitlock,
3
mais qu'est-ce qui ne va pas avec IAnimal au lieu d'AnimalInterface? bien sûr, nous avons fait tout le chemin jusqu'à notre point de départ - ce qui montre simplement que certaines des notations «hongroises» étaient utiles. Les jeter tous (à l'exception de I et T) était plus piqué que une tentative réfléchie de trouver un meilleur système.
gbjbaanb
2
@ScottWhitlock: Pour moi, IAnimalc'est beaucoup plus lisible que AnimalInterface. Les noms verbeux sont préférables, sauf dans les cas où une simple convention courte peut être utilisée pour quelque chose qui se produit assez fréquemment. Et les interfaces sont un tel cas.
maaartinus