2010-12-06 1 views
33

Ich wollte ein Objekt schreiben, das auf einer warteschlangenartigen Schnittstelle arbeitete. Ich suchte nach IQueue<T>, kam aber überraschend leer zurück.Warum gibt es keine IQueue <T> oder IStack <T> Schnittstelle in .NET Framework?

Es gibt folgende Sammlung bezogenen Schnittstellen:

  • ICollection<T>
  • IList<T>
  • IDictionary<TKey,TValue>
  • ISet<T>

Was diese Art von Sammlungen gemacht bekommen gut definierte Schnittstellen? Warum rechtfertigen Stapel und Warteschlangen keine Schnittstelle?

+4

Ein Stapel oder eine Warteschlange ist eine ziemlich triviale Implementierung einer sortierten Liste. Warum also sollten sie etwas einbauen, das wie 2 Zeilen Code ist, so dass es stattdessen 1 sein könnte? –

+1

@ Russell Steen was ist * in der Warteschlange * sortiert? Verknüpfte Liste kann sein? – Andrey

+5

@ Russell Steen Implementierungsdetails sollten kein Faktor für eine klar definierte * Schnittstelle * sein. –

Antwort

13

Nun, weil es eine Zuordnung von diesen Schnittstellen zu Klassen geben würde, die sie implementieren (außer neuste ConcurrentQueue). Aber andere erwähnte Schnittstellen haben viele Klassen, die sie implementieren.

Erweitern ein bisschen. Wir können die wahre Motivation des BCL-Teams nicht kennen. Aber ich habe das Gefühl, dass, wenn sie Queue und Stack erstellt haben, diese Klassen so trivial aussahen, dass sie beschlossen, sie nicht zu Interfaces zu abstrahieren. Der Grund liegt auf der Hand: Die Klassen sahen so einfach aus, waren aber gleichzeitig vollständig, so dass es keinen Grund gab, verschiedene Implementierungen von ihnen in BCL zu erstellen. Dann kam ConcurrentQueue und vorherige Aussage wurde etwas falsch.

Da es zeigte Queue und ConcurrentQueue nicht so viel ähnliches, um sie zu implementieren, einzelne Schnittstelle.

+0

warum wurde dies abgelehnt? – Andrey

+0

+1 Gegenschlag. Ich würde gerne sehen, die Antwort ein wenig erweitert, aber ich denke nicht, dass es verdient eine -1. –

+1

@Paul Sasik danke, ich erweiterte, – Andrey

2

Ich denke, das liegt daran, dass Stack und Queue sehr spezielle Konzepte sind und meines Wissens keine anderen Klassen eine spezielle Form eines Stacks oder einer Queue implementieren.

EDIT:

Ok, es ist jetzt ein ConcurrentQueue<T>, die meine Schlussfolgerung zu negieren scheint. Vielleicht waren die Sprachdesigner zu der Zeit, als C# 1.0 noch in der Betaphase war, der Meinung, dass es niemals eine spezielle Form einer Warteschlange/eines Stapels geben wird und jetzt ist es zu spät, um eine Schnittstelle dafür einzurichten.

Das ist eine Menge zu erraten. Ich hoffe, Eric Lippert wird diese Frage sehen und eine "offizielle" Erklärung abgeben. :-)

+0

Frage war über Generalisierung, keine Spezialisierung – Andrey

+0

@Andrey: Was ich sagen wollte, ist, dass das Konzept einer Warteschlange durch die Queue-Klasse perfekt abgedeckt wird, so dass es keine Notwendigkeit für eine Schnittstelle und eine andere Implementierung einer Warteschlange gibt. Gleiches mit Stapel. – VVS

+0

@VVS: In Bezug auf Ihre Bearbeitung ... Als MS "SortedSet " in .NET4 eingeführt hat, hat es sie nicht daran gehindert, die 'ISet ' Schnittstelle einzuführen und sie an' HashSet 'anzupassen. – LukeH

4

Ich würde vermuten, dass Sie nicht sehen, Stack oder Warteschlange Schnittstellen ist wegen der Natur der Sammlungen. Die Auflistungsschnittstellen, die Sie aufgelistet haben, die Schnittstellen haben, sind zufälliger Zugriff, während Stapel und Warteschlangen nicht sind. Sie müssen auf ganz bestimmte Weise (FIFO oder LIFO) aufgerufen werden und können daher nicht allgemein verwendet werden. Daher ist es sinnvoll, diese Sammlungen nur als generische Implementierungen, aber nicht über Schnittstellen zu verwenden. Mit anderen Worten, aufgrund der Einschränkungen, die LIFO/FIFO einer Sammlung auferlegt, gibt es sehr wenig (oder nichts), was von einer Klasse, die ein theoretisches IStack oder IQueue implementiert, anders ausgeführt werden kann.

Um diese Idee auszuüben, könnten Sie Ihren eigenen IStack und/oder IQueue erstellen und diese dann in einer Klasse implementieren. Sie werden sehen, dass die von Ihnen zur Verfügung gestellte Funktionalität vollständig übertragen wird. Z.B. Am Ende werden Anforderungen und Ergebnisse einfach an eine interne Stapel- oder Warteschlangensammlung weitergeleitet oder zurückgegeben. Und in dieser Pass-Through-Funktionalität wird es wenig oder gar keinen potenziellen Mehrwert geben.

+3

Was ist mit etwas wie 'ConcurrentQueue ' (was tatsächlich jetzt in der BCL existiert)? Denkst du nicht, dass es sinnvoll gewesen wäre, für die Queue 'und' ConcurrentQueue 'eine gemeinsame Schnittstelle zu implementieren? – LukeH

+0

@LukeH: Das ist eine speziellere Sammlung, obwohl sie immer noch der FIFO-Semantik folgt, also würde ich erwarten, dass dort eine iConcurrentQueue-Schnittstelle nicht wirklich nützlich sein würde. –

+3

Ich werde eigentlich eine 'IQueue ' Schnittstelle erstellen! Meine Implementierung verwendet einen synchronisierten Speicher, der auf der Festplatte verbleibt. Es wäre besser gewesen, eine vorhandene Schnittstelle zu verwenden, als meine eigene Sache zu definieren! –

3

Warum sollte das .NET Framework IQueue<T> und IStack<T> Schnittstellen haben? Was würden sie kaufen?

Was haben diese Arten von Sammlungen wohl definierten Schnittstellen bekommen?

Die Basisklassenbibliotheken verwenden tatsächlich alle die diese Schnittstellen (IList usw.): In jedem Fall gibt es eine Reihe von anderen Klassen, für die es mehr Sinn, mit der Schnittstelle Abstraktion als konkreter zu interagieren gemacht.

Warum gewährleisten Stacks und Warteschlangen keine Schnittstelle?

Wahrscheinlich, weil es keine BCL-Klassen waren die IStack<T> und IQueue<T> und es gab keine offensichtlichen oder wahrscheinlich Anwendungsfälle für diese Abstraktionen benötigt.

Mir ist klar, dass dies keine befriedigende philosophische Antwort ist, aber es sieht so aus, als ob die Framework-Designer wirklich pragmatisch waren, was Schnittstellen hat: Sie haben sie gemacht, wenn sie sie brauchten.

+0

Der pragmatische Aspekt ist ein guter zu betrachten. Ich würde sicherlich keine Schnittstelle schaffen, für die ich keine unmittelbare Verwendung hatte. –

+0

IMO das ist wahrscheinlich die "wahre" Antwort. Ich gehe davon aus, dass die Designer nicht viele der enthaltenen Interfaces erstellt haben, bis sie sie brauchten. –

0

Ich bezweifle, dass es einen bestimmten Grund gab. Wenn ich meine Treiber hätte, gäbe es viel mehr diskret definierte Schnittstellen, auch wenn es keine Klassen gab, die sie alleine implementierten. Zum Beispiel könnte ich einen QueueStack (Of T) implementiert haben, der IGetNext (Of T), IGetNextWait (Of T) und IClear (Of T) zusammen mit IQueue (Of T), IWaitQueue (Of T), IStack (Of T) und IWaitStack (Of T). Personen, die ein Objekt konsumieren, könnten genau spezifizieren, was sie tatsächlich benötigten, und Implementierer müssten nur das implementieren, was sie angeblich unterstützen würden.

2

Ich denke, die Existenz der neuen Klassen in .NET 4 ConcurrentQueue<T> und ConcurrentStack<T> Ihren Punkt beweisen, dass es IQueue<T> und IStack<T> Schnittstellen haben sollten. Auch wenn sie ursprünglich nicht vorhanden waren, sollten sie in .NET hinzugefügt worden sein.

Ich musste meine eigenen benutzerdefinierten Stack-Implementierungen in der Vergangenheit in .NET erstellen und stimme zu, dass eine Standardschnittstelle nützlich gewesen wäre .

Verwandte Themen