Ich bin gerade auf den ArraySegment<byte>
Typ gestoßen, als ich die MessageEncoder
Klasse unterklassifiziert habe .
Ich verstehe jetzt, dass es ein Segment eines bestimmten Arrays ist, einen Offset nimmt, nicht aufzählbar ist und keinen Indexer hat, aber ich verstehe seine Verwendung immer noch nicht. Kann jemand bitte mit einem Beispiel erklären?
ArraySegment
es in .Net 4.5 aufzählbar.Antworten:
ArraySegment<T>
ist in .NET 4.5 + und .NET Core viel nützlicher geworden, da es jetzt Folgendes implementiert:IList<T>
ICollection<T>
IEnumerable<T>
IEnumerable
IReadOnlyList<T>
IReadOnlyCollection<T>
im Gegensatz zur .NET 4-Version, die keinerlei Schnittstellen implementiert hat.
Die Klasse kann jetzt an der wundervollen Welt von LINQ teilnehmen, sodass wir die üblichen LINQ-Aufgaben ausführen können, z. B. den Inhalt abfragen, den Inhalt umkehren, ohne das ursprüngliche Array zu beeinflussen, das erste Element abrufen usw.
quelle
GetEnumerator
privat gemacht wurden, bedeutet dies, dass Sie gezwungen sind,IEnumerable<T>
(eine Box-Konvertierung) zu verwenden, um es zu nennen. Pfui!In diesem Beispiel sehen wir uns an, wie Sie das ursprüngliche Array, die Offset- und Count-Eigenschaften verwenden und wie Sie die im ArraySegment angegebenen Elemente durchlaufen können.
ArraySegment-Struktur - was dachten sie?
quelle
i < segment.Offset + segment.Count
.Es ist eine mickrige kleine Soldatenstruktur, die nichts anderes tut, als einen Verweis auf ein Array zu behalten und einen Indexbereich zu speichern. Ein wenig gefährlich, seien Sie vorsichtig, dass es keine Kopie der Array-Daten erstellt und das Array in keiner Weise unveränderlich macht oder die Notwendigkeit der Unveränderlichkeit zum Ausdruck bringt. Das typischere Programmiermuster besteht darin, das Array und eine Längenvariable oder einen Längenparameter einfach beizubehalten oder zu übergeben, wie dies bei den .NET BeginRead () -Methoden, String.SubString (), Encoding.GetString () usw. usw. der Fall ist.
In .NET Framework wird es nur wenig verwendet, außer bei einem bestimmten Microsoft-Programmierer, der an Web-Sockets gearbeitet hat und WCF gefällt. Welches ist wahrscheinlich die richtige Anleitung, wenn Sie es mögen, dann verwenden Sie es. In .NET 4.6 wurde ein Peek-a-Boo durchgeführt, das von der hinzugefügten MemoryStream.TryGetBuffer () -Methode verwendet wird.
out
Ich nehme an , zwei Argumente vorzuziehen.Im Allgemeinen steht der universellere Begriff der Slices ganz oben auf der Wunschliste der wichtigsten .NET-Ingenieure wie Mads Torgersen und Stephen Toub. Letztere
array[:]
haben vor einiger Zeit den Syntaxvorschlag gestartet. Sie können auf dieser Roslyn-Seite sehen, worüber sie nachgedacht haben . Ich würde davon ausgehen, dass es letztendlich darauf ankommt, CLR-Unterstützung zu erhalten. Dies wird für C # Version 7 afaik aktiv in Betracht gezogen. Behalten Sie System.Slices im Auge . .Update: Dead Link, dieser wurde in Version 7.2 als Span ausgeliefert .
Update2: Mehr Unterstützung in C # Version 8.0 mit Range- und Index-Typen und einer Slice () -Methode.
quelle
Was ist mit einer Wrapper-Klasse? Nur um zu vermeiden, dass Daten in temporäre Puffer kopiert werden.
Beispiel:
Ausgabe:
quelle
IEnumerable<T>
dann IEnumeratorIEnumerable.GetEnumerator() { return GetEnumerator(); }
Das ArraySegment ist VIEL nützlicher als Sie vielleicht denken. Führen Sie den folgenden Komponententest durch und lassen Sie sich überraschen!
Sie sehen, alles, was Sie tun müssen, ist ein ArraySegment in IList umzuwandeln, und es wird all die Dinge tun, die Sie wahrscheinlich erwartet haben. Beachten Sie, dass der Typ immer noch ArraySegment ist, obwohl er sich wie eine normale Liste verhält.
AUSGABE:
quelle
IList<T>
. Ich würde erwarten, dass der Indexer istpublic
.Mit einfachen Worten: Es wird auf ein Array verwiesen, sodass Sie mehrere Verweise auf eine einzelne Array-Variable haben können, von denen jede einen anderen Bereich hat.
Tatsächlich hilft es Ihnen, Abschnitte eines Arrays strukturierter zu verwenden und zu übergeben, anstatt mehrere Variablen zu haben, um Startindex und Länge zu halten. Außerdem bietet es Sammlungsschnittstellen, mit denen Sie einfacher mit Array-Abschnitten arbeiten können.
Zum Beispiel machen die folgenden zwei Codebeispiele dasselbe, eines mit ArraySegment und eines ohne:
und,
Offensichtlich ist das erste Code-Snippet bevorzugter, insbesondere wenn Sie Array-Segmente an eine Funktion übergeben möchten.
quelle