| 

.NET C# Java Javascript Exception

6
Nachdem mir heute Morgen die Frage beantwortet wurde Warum kann ich bei EntityCollection nicht auf eine per Interface definierte Methode direkt zugreifen? wurde mir klar das ich das Konzept des "expliziten Implementierung eines Interface" nicht kenne.

Wozu ist dieses Konzept da bzw. welche Designentscheidungen führen dazu das man dieses Konzept nutzt?
01.04.2011
Thomas Sczyrba 1,4k 1 2 9
3 Antworten
7
Neben der von Andi genannten Auflösung von Namenskonflikten beim Implementieren mehrerer Interfaces ist ein weiterer möglicher Grund, nach außen absichtlich verbergen zu wollen, dass das Interface implementiert wird.

Dies kann dann nützlich sein, wenn das Interface nur in einem bestimmten Kontext benötigt wird: ein Framework verlangt möglicherweise, dass meine Klasse ein bestimmtes Interface implementiert, damit ich sie zusammen mit dem Framework benutzen kann. Für Nutzer außerhalb des Framework sind die Member des Interface aber völlig uninteressant bzw. es ergäbe überhaupt keinen Sinn, sie zu nutzen. Dann kann ich mit einer expliziten Interface-Implementierung die öffentliche Sicht meiner Klasse "sauber" halten und sie trotzdem mit dem Framework verwenden.

Dieser Fall dürfte bei deiner vorigen Frage vorliegen: laut Doku ist IListSource explizit für Binding-Szenarien vorgesehen. D.h. es ist nicht davon auszugehen, dass "handgeschriebener" Code die Member von IListSource aufrufen wird/soll. Deshalb implementiert die EntityCollection dieses Interface explizit und kann somit für Datenbindung verwendet werden, ohne dass die IListSource-Member nach außen sichtbar sind und für Verwirrung oder Fehler in der Nutzung von EntityCollection sorgen.

Die "Framework Design Guidelines" von Cwalina und Abrams (sehr empfehlenswerte Lektüre übrigens!) nennen noch zwei weitere Situationen, in denen explizite Implementierung in Frage kommt:

  • Änderung des Rückgabetyps einer implementierten Methode, z.B.
    public class StringCollection : IList
    {
    public string this[int index] {...} //dieser Indexer soll verwendet werden
    object IList.this[int index] {...} //den untypisierten Indexer verlangt IList
    }

  • absichtliches Verbergen eines "ungeeignet" benannten Members und "Ersetzen" durch einen Member mit äquivalenter Funktion, aber "besserem" Namen. Beispiel: Dispose und Close in einem Stream sollen exakt das gleiche tun. Close passt für einen Stream als Name eigentlich besser, aber IDisposable soll implementiert werden. Lösung: IDisposable explizit implementieren und auf Close delegieren. Achtung: das kann anderserseits auch zu Verwirrung führen und sollte deshalb nur mit großer Vorsicht und Überlegung eingesetzt werden.
01.04.2011
Matthias Hlawatsch 13,2k 4 9
Vielen Dank. Das waren sehr erhellende Informationen. Jetzt bekommst du schon das dritte mal in Folgeg +1 von mir.
Thomas Sczyrba 01.04.2011
5
Ein möglicher Grund ist wenn eine Klasse z.B. zwei Interfaces implementiert welche je eine Add-Methode definieren, sich aber unterschiedlich verhalten sollen (abhängig vom Interface) -oder- Methoden welche sich z.B. nur über den Rückgabewert unterscheiden.
01.04.2011
Andi 151 5
0
Danke für die bisherigen Antworten. Für alle die es interessiert:

Habe mir das von Matthias empfohlene Buch besorgt ISBN: 3827324548 Noch ausführlicher ist das Thema in "Microsoft Framework Programmierung in C#" erklärt ISBN: 3860639846. Werde mir jetzt dieses Wochenende mal die Zeit nehmen und ausführlich darüber lesen.
01.04.2011
Thomas Sczyrba 1,4k 1 2 9

Stelle deine Oop-Frage jetzt!