Während einer meiner Studien zu den Feinheiten von C # stieß ich auf eine interessante Passage zur expliziten Implementierung von Schnittstellen.
While this syntax is quite helpful when you need to resolve name clashes,
you can use explicit interface implementation simply to hide more "advanced"
members from the object level.
Der Unterschied zwischen dem Erlauben object.method()
oder dem Erfordernis des Gießens ((Interface)object).method()
scheint für meine unerfahrenen Augen eine böse Verschleierung zu sein. Der Text darauf hingewiesen , dass dies die Methode von Intellisense auf Objektebene verbergen, aber warum sollen Sie wollen , das zu tun , wenn es nicht notwendig , Namenskonflikte zu vermeiden?
c#
design
interfaces
Nathanus
quelle
quelle
Antworten:
Stellen Sie sich eine Situation vor, in der eine Schnittstelle eine Klasse zwingt, Methoden zu implementieren, die als Teil der Klasse nicht sinnvoll sind. Dies kann häufig vorkommen, wenn die Schnittstellen besonders groß sind und gegen das Prinzip der Schnittstellentrennung verstoßen.
Diese Klasse muss die Schnittstelle implementieren, aber anstatt ihre gut sichtbare öffentliche Schnittstelle mit Methoden zu verschmutzen, die keinen Sinn ergeben, können Sie explizit die Methoden implementieren, die offensichtlich nicht verfügbar sein sollen. Die gut sichtbare öffentliche Schnittstelle der Klasse gibt an, wie die Klasse verwendet werden soll, und die explizite Implementierung ist vorhanden, wenn auf die Klasse über die Schnittstelle zugegriffen wird.
quelle
IEnumerable<T>
gewünscht wird, die sich wie die Verkettung von zwei anderen verhält. WennIEnumerable<T>
eine Eigenschaft enthalten ist, die angibt, ob ihre Anzahl bekannt ist, möglicherweise unendlich ist oder keine, und eine Methode, um zu fragen, wie hoch die Anzahl ist, kann eine Klasse, die mehrere aggregiertIEnumerable<T>
und sich wie eine Verkettung verhält, ihre Anzahl effizient melden, falls einige von Die gekapselten Sammlungen kannten ihre Anzahl.Die nützlichste Anwendung, die ich gefunden habe, ist die Implementierung von Fabriken. In vielen Fällen ist es nützlich, Klassen zu erstellen, die innerhalb der Factory veränderbar, aber für externe Klassen unveränderlich sind. Dies kann einfach in Java mithilfe innerer Klassen implementiert werden, indem die Felder und ihre Setter privat gemacht werden und die Getter nur als öffentliche Mitglieder verfügbar gemacht werden. In C # musste ich jedoch explizite Schnittstellen verwenden, um dasselbe zu erreichen. Ich werde weiter erklären:
In Java können die innere Klasse UND die äußere Klasse auf private Mitglieder zugreifen, was absolut sinnvoll ist, da die Klassen sehr eng miteinander verbunden sind. Sie befinden sich in derselben Codedatei und werden wahrscheinlich von demselben Entwickler entwickelt. Dies bedeutet, dass die Fabrik weiterhin auf private Felder und Methoden in der inneren Klasse zugreifen kann, um deren Werte zu ändern. Externe Klassen können jedoch nur über ihre öffentlichen Getter auf diese Felder zugreifen.
In C # können äußere Klassen jedoch nicht auf private Mitglieder innerer Klassen zugreifen, sodass das Konzept nicht direkt anwendbar ist. Ich habe eine explizite Schnittstelle als Problemumgehung verwendet, indem ich eine private Schnittstelle in der äußeren Klasse definiert und explizit in der inneren Klasse implementiert habe. Auf diese Weise kann nur die äußere Klasse auf die Methoden in dieser Schnittstelle zugreifen, wie dies in Java der Fall ist (es müssen jedoch Methoden sein, keine Felder).
Beispiel:
Dafür würde ich explizite Schnittstellen verwenden.
quelle
Wenn eine Klasse zwei Schnittstellen implementiert, die ein Mitglied mit derselben Signatur enthalten, führt die Implementierung dieses Mitglieds in der Klasse dazu, dass beide Schnittstellen dieses Mitglied als Implementierung verwenden. Im folgenden Beispiel
Paint
rufen alle Aufrufe dieselbe Methode auf. C #Im Gegensatz dazu können Sie durch die explizite Implementierung eines (oder beider) von ihnen für jedes ein anderes Verhalten angeben.
quelle
Explizite Schnittstellen sind praktisch, wenn ein Objekt zwei oder mehr sehr unterschiedliche Kommunikationsformen aufweist.
Beispiel: Ein Objekt, das eine Sammlung von untergeordneten Objekten verwaltet, die mit dem übergeordneten Objekt kommunizieren müssen.
Es gibt einige Aktionen, auf die nur externe Anrufer zugreifen sollen, und einige Aktionen, auf die nur untergeordnete Objekte zugreifen sollen.
Explizite Schnittstellen tragen dazu bei, diese Kluft zu gewährleisten.
quelle
Vielleicht, wenn Sie Funktionen hatten, die für die Benutzer nützlich waren, aber nur, wenn Sie wirklich wissen, was Sie tun (genug, um die Dokumentation gelesen zu haben, um mehr über die Funktion zu erfahren), aber das kann wahrscheinlich zu Problemen führen, wenn Sie dies nicht tun.
Warum Sie das tun würden, anstatt eine zweite "Advanced Features Interface" bereitzustellen, weiß ich nicht.
quelle
Code wird im Allgemeinen mehr gelesen als geschrieben und ich verwende Intellisense nur, um Code schnell zu schreiben. Ich würde keinen bestimmten Code schreiben, um Intellisense schöner zu machen.
Ich sehe nicht besonders wie
((Schnittstellen-) Objekt) .method () ist nicht lesbarer als object.method ().
Wenn ich viele Methoden für ein bestimmtes Objekt hätte, könnte ich mich fragen, ob es ein Gottobjekt ist oder nicht und sollte tatsächlich in mehrere einfachere Objekte aufgeteilt werden.
quelle