Was ist der Grund für die Namenskonvention "I" für Schnittstellen in .NET?

10

Ich weiß, dass es die "I" -Konvention seit COM gibt, aber ich habe nie verstanden, warum sie nicht wie jede andere Namenskonvention vor .NET überdacht wurde.

In Bezug auf den Verbrauch ist das einzige, was eine Schnittstelle beispielsweise von einer abstrakten Klasse unterscheidet, dass sie mehrfach vererbt werden können. Aber alles nach Visual Studio 2003 hat Typensignaturen in QuickInfos angezeigt, sodass es genauso nutzlos ist wie alle anderen ungarischen Notationen, die verworfen wurden.

Ich dachte auch, dass es so sein könnte, dass Sie eine grundlegende Implementierung der Schnittstelle mit demselben Namen haben können, z. B. Messageerben IMessage, aber die meisten .NET-Bibliotheken haben System.Collections.ReadOnlyCollectionBasestattdessen das Wort "Base" am Ende hinzugefügt (z. B. ) - und das macht semantischer Sinn.

COM-Interop scheint ein weiterer möglicher Grund zu sein - aber es ist nicht so, dass die von ihm generierten Wrapper-Klassen vollkommen idiomatisch .NET sind, daher bezweifle ich, dass dies eine ästhetische Überlegung war.

In einem meiner neueren Projekte habe ich ganz auf die Konvention verzichtet und es fühlt sich gut an. Fehlt mir etwas?

Rei Miyasaka
quelle
1
Sie erben keine Schnittstellen, um sie zu erfüllen, großer Unterschied.
Daniel Little
Es scheint auch eine Präferenz wie IList und List im Gegensatz zu List und ArrayList zu sein. Sie haben es wahrscheinlich getan, weil IList keine ListBase ist, sondern wirklich eine ListInterface (keine List of Type-Schnittstelle), wenn Sie verstehen, was ich meine.
Daniel Little
@Lavinski In .NET IListist ein allgemeiner Begriff für eine sequenzierte, zusammenhängende Sammlung mit wahlfreiem Zugriff, während Listes sich um eine sequenzierte, zusammenhängende, wahlfreie Sammlung mit wachsendem Zugriff handelt . Ich denke , F # , sie habe Recht in Aliasing Listzu ResizeArray; Das ist definitiv ein viel aussagekräftigerer Name. IListdann hätte es sein können List, also scheint das auch kein Grund zu sein.
Rei Miyasaka
2
IBaseBall und IBaseBallBase sind für mich sinnvoller als BaseBallBase und BaseBallBaseBase (dummes Beispiel, ich weiß: D)
e-MEE
@ e-MEE wäre ebenso albern IIRC, das eine Schnittstelle für das IRC-Chat-Protokoll sein könnte, oder das Akronym für "wenn ich mich richtig erinnere".
Rei Miyasaka

Antworten:

12

Ich denke, dies ist möglicherweise der einzige Fall, in dem Präfixe nützlich sind.

Klassen und Schnittstellen haben wirklich unterschiedliche Semantiken und sind, da beide Typen sind, leicht zu verwechseln.
Wenn ich eine Klassendeklaration sehe, kann ich sofort erkennen, woraus sie stammt und was sie implementiert :

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

Es wäre schwieriger zu verstehen, wenn die Definition so aussehen würde

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

Und wie würden Sie anrufen ListClass? Natürlich nicht nur, ListBaseweil es für sich allein verwendbar ist.
Wir müssen also entweder ein Problem lösen, das wir gerade erfunden haben, oder ein Präfix anpassen, das Klassen von Schnittstellen trennt, wie es .NET Framework-Designer getan haben.

Ich persönlich finde es auch nützlich, wenn ich anhand der Methodensignatur erkennen kann, dass es mit Schnittstellen funktioniert.

public void PrintLines (IEnumerable<string> source)

Es ist wie ein Signal an meinen Kopf: Hey, ich kann das umsetzen! Ich kann die Methode füttern, was auch immer dem Vertrag entspricht.

Natürlich kann man argumentieren, dass es nicht so wichtig ist, aber dies ist eines dieser kleinen Dinge, die das Präfix für mich wert machen. Dies ist besonders nützlich, wenn Sie viel Code mit IoC-Containern schreiben, wenn Sie ständig mit Schnittstellen arbeiten und leicht zwischen beiden unterscheiden müssen.

Übrigens haben nicht nur die Schnittstellen Präfixe im System vom Typ .NET. Vergessen Sie nicht die generischen Typparameter:

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

Dies ist eine andere Situation, in der es äußerst nützlich ist, zwischen Klassen und anderen Arten von Typen unterscheiden zu können.

Dan
quelle
2
Sie können das leicht verstehen, wenn Sie wissen, dass "die erste Klasse Vererbung ist, die zweite Klasse und her Schnittstellen sind".
Saeed Neamati
3
Dies scheint ein plausibler Grund zu sein. Java scheint es ein bisschen besser gelöst zu haben, indem es einfach Schlüsselwörter verwendet, um die Liste zu verdeutlichen : class Dog extends Mammal implements MailmanChaser. @Saeed Sie können eine Klasse haben, die von nichts erbt. Der erste Typ in der Liste ist also eher eine Schnittstelle als eine Basisklasse.
Rei Miyasaka
+1 für den fettgedruckten Teil, obwohl ich mir einen anderen Ort vorstellen kann, an dem eine Präfix-basierte Konvention hilfreich gewesen wäre: zwischen einem Feld zu unterscheiden, das das ausschließliche Eigentum an einem int[](oder einem anderen Objekt veränderlichen Typs) enthält, das es mutieren kann, aber nicht share und eine, die das gemeinsame Eigentum an einem kapselt int[], das, obwohl sein Typ eine Mutation zulässt, niemand mutieren darf.
Supercat
6

Ich glaube nicht, dass du etwas vermisst, es ist nur eine historische Gewohnheit.

Ich stimme Ihnen ebenfalls zu und habe das Ich bei einigen kleinen bis mittleren Projekten ohne nachteilige Auswirkungen fallen gelassen.

Chris Lee
quelle
2
Was jedoch seltsam ist, ist, dass sie praktisch jede andere veraltete Konvention außer dieser verworfen haben. Die Geschichte erklärt es auch nicht ganz. Ich habe immer noch das Gefühl, dass es einen Grund gegeben haben muss, es sei denn, es war wirklich nur Innenpolitik - aber selbst dann kann ich keinen Grund sehen, warum sich jemand darüber aufregen würde, dass ich fallen gelassen werde.
Rei Miyasaka
2

Ich denke, der einzige Grund gemäß den Namensrichtlinien von Microsoft für Schnittstellen und Klassen ist, dass manchmal Konflikte zwischen dem Namen der Schnittstelle und der Klasse auftreten, die diese implementiert. Dies geht auf die Tatsache zurück, dass Schnittstellen tatsächlich das Skelett und nicht das Fleisch sind und die Implementiererklasse tatsächlich das Fleisch ist (Realisierung der Blaupause). Daher beschreibt IAnimal nur, was ein Tier haben sollte , während Animal Ihnen sagen kann, was es hat .

Ich persönlich stimme Ihnen jedoch in dem Punkt vollkommen zu, dass wir einfach Animal Base für die Benutzeroberfläche und Animal für die Klasse verwenden könnten .

Andererseits widersprechen sich manchmal zwei Dinge so sehr, dass ein Team beschließt, trotz bereits getroffener Entscheidungen eine Konvention vorzusehen, um weitere Konflikte zu verhindern. In ASP.NET MVC sind beispielsweise sowohl Teilansichten als auch Layouts (Masterseiten) wie eine normale Ansicht , bieten jedoch unterschiedliche Funktionen. Daher schlägt Microsoft trotz der Betonung, bei der Benennung keinen Unterstrich zu verwenden, vor, Layouts und Teilansichten mit einem Unterstrich zu unterstreichen.

Saeed Neamati
quelle
Was ist los mit AnimalInterfacestatt AnimalBase? Es ist keine Basisklasse, es ist eine Schnittstelle.
Scott Whitlock
3
aber was ist los mit IAnimal anstelle von AnimalInterface? Sicher sind wir den ganzen Weg dahin gegangen, wo wir angefangen haben - was nur zeigt, dass einige der "ungarischen" Notationen nützlich waren. Sie alle rauszuwerfen (außer I und T) war eher pikant als ein nachdenklicher Versuch, ein besseres System zu finden.
Gbjbaanb
2
@ScottWhitlock: Für mich IAnimalist viel besser lesbar als AnimalInterface. Ausführliche Namen sind vorzuziehen, außer in Fällen, in denen eine einfache kurze Konvention für etwas verwendet werden kann, das häufig genug auftritt. Und Schnittstellen sind ein solcher Fall.
Maaartinus