Ist IList <T> schlechter als T [] oder List <T>?

Die Antworten auf Fragen wie diese:List <T> oder IList <T> scheint immer der Meinung zu sein, dass die Rückgabe einer Schnittstelle besser ist als die Rückgabe einer konkreten Implementierung einer Sammlung. Aber ich kämpfe damit. Das Instanziieren einer Schnittstelle ist nicht möglich. Wenn Ihre Methode eine Schnittstelle zurückgibt, gibt sie tatsächlich noch eine bestimmte Implementierung zurück. Ich habe ein bisschen damit experimentiert, indem ich 2 kleine Methoden geschrieben habe:

public static IList<int> ExposeArrayIList()
{
    return new[] { 1, 2, 3 };
}

public static IList<int> ExposeListIList()
{
    return new List<int> { 1, 2, 3 };
}

Und benutze sie in meinem Testprogramm:

static void Main(string[] args)
{
    IList<int> arrayIList = ExposeArrayIList();
    IList<int> listIList = ExposeListIList();

    //Will give a runtime error
    arrayIList.Add(10);
    //Runs perfectly
    listIList.Add(10);
}

In beiden Fällen, wenn ich versuche, einen neuen Wert hinzuzufügen, gibt mein Compiler keine Fehler aus, aber offensichtlich die Methode, die mein Array als @ ausstellIList<T> gibt einen Laufzeitfehler aus, wenn ich versuche, etwas hinzuzufügen. Leute, die nicht wissen, was in meiner Methode vor sich geht, und Werte hinzufügen müssen, sind gezwungen, zuerst mein @ zu kopiereIList zu einerList um fehlerfrei Werte hinzufügen zu können. Natürlich können sie einen Typcheck durchführen, um zu sehen, ob sie es mit einem @ zu tun habeList oder einArray, aber wenn sie das nicht tun und der Sammlung Elemente hinzufügen möchtenSie haben keine andere Wahl, um das @ zu kopierIList zu einerList, auch wenn es bereits ein @ iList. Sollte ein Array niemals als @ verfügbar gemacht werdeIList?

Ein anderes Anliegen von mir basiert auf der akzeptierten Antwort deslinked question (Hervorhebung von mir):

Wenn Sie Ihre Klasse über eine Bibliothek zugänglich machen, die andere verwenden,Sie möchten es im Allgemeinen über Schnittstellen und nicht über konkrete Implementierungen verfügbar machen. Dies ist hilfreich, wenn Sie die Implementierung Ihrer Klasse später ändern, um eine andere konkrete Klasse zu verwenden. In diesem Fall müssen die Benutzer Ihrer Bibliothek ihren Code nicht aktualisieren, da sich die Benutzeroberfläche nicht ändert.

Wenn Sie es nur intern verwenden, ist es Ihnen vielleicht nicht so wichtig, und die Verwendung von List ist möglicherweise in Ordnung.

Stellen Sie sich vor, jemand hat mein @ tatsächlich benutzIList<T> sie haben von meinemExposeListIlist() -Methode einfach so, um Werte hinzuzufügen / zu entfernen. Alles funktioniert gut. Aber jetzt, wie die Antwort schon sagt, weil die Rückgabe einer Schnittstelle flexibler ist, gebe ich ein Array anstelle einer Liste zurück (kein Problem auf meiner Seite!), Dann sind sie auf der Suche nach einer Belohnung ...

TLDR:

1) Das Anzeigen einer Schnittstelle verursacht unnötige Casts? Ist das egal?

2) Manchmal, wenn Benutzer der Bibliothek keine Umwandlung verwenden, kann der Code beim Ändern der Methode beschädigt werden, obwohl die Methode einwandfrei bleibt.

Ich überdenke das wahrscheinlich, aber ich bin mir nicht einig, dass die Rückgabe einer Schnittstelle der Rückgabe einer Implementierung vorzuziehen ist.

Antworten auf die Frage(10)

Ihre Antwort auf die Frage