Wie verbessert Go die Produktivität mit „impliziten“ Schnittstellen und wie ist dies mit der Vorstellung von Erweiterungsmethoden in C # vergleichbar?

21

Im Go Language Tutorial erklären sie , wie Schnittstellen funktionieren:

Go hat keine Klassen. Sie können jedoch Methoden für Strukturtypen definieren. Der Methodenempfänger wird in einer eigenen Argumentliste zwischen dem Schlüsselwort func und dem Methodennamen angezeigt.

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

Ein Schnittstellentyp wird durch eine Reihe von Methoden definiert. Ein Wert vom Typ interface kann einen beliebigen Wert enthalten, der diese Methoden implementiert.

Dies ist die einzige Möglichkeit, eine Benutzeroberfläche in Go zu erstellen. Google erklärt weiter, dass:

Ein Typ implementiert eine Schnittstelle durch Implementieren der Methoden. Es gibt keine explizite Absichtserklärung interface.

Implizite Schnittstellen entkoppeln Implementierungspakete von den Paketen, die die Schnittstellen definieren: keine hängt von der anderen ab.

Es unterstützt auch die Definition präziser Schnittstellen, da Sie nicht jede Implementierung finden und mit dem neuen Schnittstellennamen versehen müssen.

Dies klingt alles verdächtig nach Erweiterungsmethoden in C # , mit der Ausnahme, dass Methoden in Go rücksichtslos polymorph sind. Sie funktionieren mit jedem Typ , der sie implementiert.

Google behauptet, dies fördere eine rasche Entwicklung, aber warum? Geben Sie etwas auf, indem Sie sich von expliziten Schnittstellen in C # entfernen? Können mit Erweiterungsmethoden in C # einige der Vorteile von Go-Schnittstellen in C # abgeleitet werden?

Robert Harvey
quelle
Siehe auch
Robert Harvey
1
Diese Go-Schnittstellen ähneln eher den Funktionen von C ++ - Vorlagen als den C # -Erweiterungsmethoden. In C # gibt es nichts Vergleichbares wie „Jeder Typ, der die Methoden A und B implementiert“. Sie können dies jedoch mit C ++ - Vorlagen tun.
SVICK
Siehe auch
Robert Harvey
Sind "implizite Schnittstellen" nicht nur eine Form des Tippens?
Allon Guralnek
"Ist 'implizite Schnittstellen' nicht nur eine Form des Tippens?" Go's Interfaces sind ein Beispiel für die strukturelle Typisierung. Sehr ähnliches Konzept.
Mortdeus

Antworten:

12

Ich sehe Erweiterungsmethoden und implizite Schnittstellen überhaupt nicht als gleich an.

Sprechen wir zuerst mit dem Zweck.

Erweiterungsmethoden existieren als syntaktischer Zucker, um Ihnen die Möglichkeit zu geben, eine Methode so zu verwenden, als ob sie ein Mitglied eines Objekts wäre, ohne Zugriff auf die Interna dieses Objekts zu haben. Ohne Erweiterungsmethoden können Sie genau dasselbe tun, Sie bekommen einfach nicht die angenehme Syntax someObjectYouCantChange.YourMethod()und müssen eher aufrufen YourMethod(someObjectYouCantChange).

Der Zweck impliziter Schnittstellen ist jedoch, dass Sie eine Schnittstelle für ein Objekt implementieren können, auf das Sie keinen Zugriff haben. Dies gibt Ihnen die Möglichkeit, eine polymorphe Beziehung zwischen jedem Objekt, das Sie selbst schreiben, und jedem Objekt herzustellen, auf das Sie keinen Zugriff haben.

Sprechen wir jetzt über die Konsequenzen.

Erweiterungsmethoden haben wirklich keine. Dies steht in perfekter Übereinstimmung mit den rücksichtslosen Sicherheitsbeschränkungen, mit denen .NET versucht, bestimmte Perspektiven eines Modells zu unterstützen (die Perspektive von innen, außen, vom Erben und vom Nachbarn). Die Folge ist nur eine syntaktische Angenehmheit.

Die Folgen impliziter Schnittstellen sind einige Dinge.

  • Eine versehentliche Implementierung der Schnittstelle kann ein glücklicher Zufall sein oder eine versehentliche Verletzung des LSP, wenn Sie die Schnittstelle einer anderen Person treffen, die Sie nicht beabsichtigt haben, ohne die Absicht des Vertrags zu beachten.
  • Die Möglichkeit, eine Methode dazu zu bringen, ein Mock eines bestimmten Objekts überhaupt zu akzeptieren, indem die Schnittstelle dieses Objekts einfach gespiegelt wird (oder sogar nur eine Schnittstelle erstellt wird, die die Anforderungen dieser Methode erfüllt und nicht mehr).
  • Die Fähigkeit, Adapter oder andere verschiedene ähnliche Muster mit mehr Leichtigkeit in Bezug auf Objekte zu erstellen, in die Sie sich nicht einmischen können.
  • Verzögern Sie die Schnittstellenimplementierung und implementieren Sie sie später, ohne die eigentliche Implementierung berühren zu müssen. Implementieren Sie sie nur, wenn Sie tatsächlich einen anderen Implementierer erstellen möchten.
Jimmy Hoffa
quelle
Die Nützlichkeit von Erweiterungsmethoden in Linq beruht zu einem großen Teil auf ihrer Fähigkeit, eine Methodenimplementierung auf eine Schnittstelle zu übertragen, insbesondere IEnumerableund IQueryable. Während Sie dies mit staticMethoden in einer Utility-Klasse vortäuschen könnten , wäre dies umständlich.
Robert Harvey
@RobertHarvey Es ist nicht unbedingt korrekt zu behaupten, dass die Methode einer Schnittstelle zugeordnet ist. Beachten Sie den Unterschied zwischen einer tatsächlichen Methode einer Schnittstelle und einer Erweiterungsmethode: Eine Methode einer Schnittstelle wird innerhalb der Klasse implementiert, die diese Schnittstelle implementiert, und daher hat mehr Zugriff als jede andere Erweiterungsmethode. Auch hier ist es ein Perspektivwechsel. Code, der innerhalb einer Klasse implementiert wird, erhält im Vergleich zu außen eine besondere Perspektive.
Jimmy Hoffa