Eigentlich ist das ja eine Anfängerfrage. Aber ich hab mir auf Grund einer Frage darüber mal Gedanken gemacht.
Zum einen ist es mir vollkommen klar, dass man mit Interfaces eine gewisse Abstraktion von Objekten erreichen kann. Sinnvollstes Einsatzgebiet ist wohl die lose Kopplung von Komponenten (Trennung GUI - Logik etc.)
Aber was mir aufgefallen ist, ist folgendes:
IList<String> list = new List<String>();
Warum nehm ich da ein Interface her? Wirklich eine blöde Frage muss ich zugeben. Das lustige ist, dass ich das immer so mache ohne darüber nachzudenken.
Ich hab mir die Arbeit gemacht und ein paar Quelltexte von OpenSource-Projekte durchgesehen und auch da gibt es sehr viele Entwickler, die das ebenso machen.
Aber wie erklär ich erklär ich jetzt einem Anfänger, warum ich das so mache? Ich weiß es ja selbst nicht 😃
Du machst es so, weil du es mal so gesehen hast.
Es kann richtig so sein, es kann auch falsch sein, der Zusammenhang macht es.
Mit Interfaces arbeitet man i.a. bei Properties, Parameterübergaben und -rückgaben sowie bei DI/IOC.
Bei Aufrufen benutzt man den minimalsten Typ um dem Aufrufenden mehr Möglichkeiten bei der Erstellung der jeweiligen Daten zu geben, also z.b. IList, IEnumerable usw. halt das Minimalste womit man arbeiten kann.
Bei Rückgaben benutzt man sie um Implementationsdetails zu verbergen, die den Aufrufenden nicht zu interessieren haben, und die sich ggf ändern können.
Wenn du aber in der Routine eine List<T> erzeugst hat das einen konkreten Hintergrund, und sie dann einer IList<T> zuweist ist selten sinnvoll, denn hier hast du ja vollen Zugriff auf die Details.
Bei der Rückgabe als Funktionsergebnis dann eine IList<T> draus zu machen ist dann allerdings wieder sinnvoll, das passiert aber automatisch.
Hallo,
ich denke der Titel des Threads [war: "Warum verwendet man Interfaces?"] ist etwas unglücklich gewählt. Wie du ja schon geschrieben hast, liegt der Sinn unter anderem in der losen Kopplung von Komponenten.
Dein gewähltes Beispiel ist ja nicht gerade ein Paradebeispiel für die Verwendung von Interfaces, zumal du in der gleichen Zeile die konkrete Implementierung dazu spezifizierst.
Ein etwas passenderes Beispiel wäre:
private void DoSomething(IEnumerable<string> strings)
{
...
}
Hier könnte man einem Anfänger verdeutlichen, dass durch die abstrakte Verwendung einer Schnittstelle (IEnumerable<T>), die Wiederverwendung gesteigert wird, da die Methode für alle Objekte funktioniert, die dieses Interface implementierung, also List<T>, Collection<T>, Arrays etc.
Normalerweise programmiere ich auch immer gegen Schnittstellen. Aber innerhalb einer Methode sehe ich das nicht so eng, z. B.:
private void DoSomething()
{
var list = new List<string>();
list.Add("Hello");
// more code
}
}
Ok. Dann lag ich also mit meiner Annahme richtig, dass das eigentlich keinen Sinn macht. Die anderen Beispiel sind ja alle klar und ich glaub, die hab ich auch entsprechend richtig erklärt (Ob er es verstanden hat, wird sich noch zeigen)
Die Frage kam eben auf, als er ein Programm von mir als Beispiel angesehen hat. Davor ist mir das nie aufgefallen 😃
Danke für die Antworten
Hallo Mossi,
die ursprüngliche Frage aus dem Titel "Warum verwendet man Interfaces?" wurde im Forum schon oft beantwortet. Am ausführlichsten in
Interface, Klassen und Vererbung ?
Abstrakte Klasse vs Interface
Warum immer gegen Interfaces programmieren?
Das müssen wir bitte nicht noch mal von Null an besprechen. Auch nicht den Punkt, mit den Parametern und Rückgabewerten, auf den nicht nur FZelle und Sarc ausführlich und korrekt eingegangen sind, sondern der auch schon mehrfach im Forum besprochen wurde, u.a. in
IList<T> oder List<T> als Parameter- bzw. Rückgabetyp?
[gelöst] Konkreter Typ oder Interface als Rückgabetyp?
Bleibt also die eigentliche Frage, die ich deshalb explizit in den Titel geschrieben habe. Und auch die wurde schon fast beantwortet: Der lokale Variablen den Interface-Typ zu geben, macht in dem konkreten Listenbeispiel im Grunde keinen Sinn.
Höchstens, wenn der Variable im Laufe der Zeit bzw. je nach eingeschlagenem Codepfad Objekte unterschiedlicher Klassen zugewiesen werden sollen, die alle IList<String> implementieren. Bei einer lokalen Variablen ist das aber eher unwahrscheinlich. Bei einem Feld könnt das schon eher der Fall sein. Da könnte es dann Sinn machen.
Auf jeden Fall anders sieht es bei der Verwendung von DI/IoC aus. Folgendes wäre sinnvoll:
ICustomer = ioc.Resolve<ICustomer>;
Aber da wird eben sowohl links als auch rechts der Interface-Typ verwendet.
herbivore