Ich habe ein Array X von 10 Elementen. Ich möchte ein neues Array erstellen, das alle Elemente aus X enthält, die bei Index 3 beginnen und bei Index 7 enden. Natürlich kann ich leicht eine Schleife schreiben, die dies für mich erledigt, aber ich möchte meinen Code so sauber wie möglich halten . Gibt es eine Methode in C #, die das für mich tun kann?
So etwas wie (Pseudocode):
Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)
Array.Copy
passt nicht zu meinen Bedürfnissen . Ich brauche die Elemente im neuen Array, um Klone zu sein. Array.copy
ist nur ein C-Style- memcpy
Äquivalent, es ist nicht das, wonach ich suche.
Antworten:
Sie können es als Erweiterungsmethode hinzufügen:
Aktualisieren Sie das erneute Klonen (was in der ursprünglichen Frage nicht offensichtlich war). Wenn Sie wirklich einen tiefen Klon wollen; etwas wie:
Dies erfordert jedoch, dass die Objekte serialisierbar (
[Serializable]
oderISerializable
) sind. - Sie könnten für andere Serializer gegebenenfalls leicht ersetzenXmlSerializer
,DataContractSerializer
, protobuf-net etc.Beachten Sie, dass Deep Clone ohne Serialisierung schwierig ist. Insbesondere
ICloneable
ist es in den meisten Fällen schwer zu vertrauen.quelle
Sie können verwenden,
Array.Copy(...)
um in das neue Array zu kopieren, nachdem Sie es erstellt haben, aber ich glaube nicht, dass es eine Methode gibt, die das neue Array erstellt und eine Reihe von Elementen kopiert.Wenn Sie mit .NET 3.5 Sie können LINQ verwenden:
aber das wird etwas weniger effizient sein.
In dieser Antwort auf eine ähnliche Frage finden Sie Optionen für spezifischere Situationen.
quelle
Haben Sie darüber nachgedacht, zu verwenden
ArraySegment
?http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx
quelle
IEnumerable<T>
und eine Vielzahl anderer nützlicher Schnittstellen.ArraySegment
die ursprüngliche Frage beantworten?IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
Ich sehe, Sie möchten klonen und nicht nur Referenzen kopieren. In diesem Fall können Sie
.Select
Array-Mitglieder auf ihre Klone projizieren. Wenn Ihre Elemente beispielsweise implementiert sind, könnenIClonable
Sie Folgendes tun:Hinweis: Für diese Lösung ist .NET Framework 3.5 erforderlich.
quelle
IEnumerable
. Ich kann eine bekommenIEnumerable
,IList
,IArray
usw ... mit minimalem Aufwand, Inline , wenn ich muss. Wenn ich die tiefe Kopie nicht brauche, entferne ich einfach dieSelect
. FallenlassenSkip
oderTake
erlaubt mir, die Reichweite zu kontrollieren. Alternativ kann ich es mitSkipWhile
und / oder verwechselnTakeWhile
.Der folgende Code macht es in einer Zeile:
quelle
In C # 8 haben sie eine neue eingeführt
Range
undIndex
Artquelle
quelle
Aufbauend auf Marc's Antwort, aber Hinzufügen des gewünschten Klonverhaltens
Und wenn die Implementierung von ICloneable zu viel wie harte Arbeit ist, reflektieren Sie sie mithilfe der kopierbaren Bibliothek von Håvard Stranden , um das erforderliche schwere Heben zu erledigen.
Beachten Sie, dass die OX.Copyable-Implementierung mit folgenden Funktionen funktioniert:
Dies sollte also fast jede Situation abdecken, die Sie haben. Wenn Sie Objekte klonen, in denen das Subdiagramm Dinge wie Datenbankverbindungen oder Datei- / Stream-Handles enthält, haben Sie offensichtlich Probleme, aber das gilt für jede verallgemeinerte tiefe Kopie.
Wenn Sie stattdessen einen anderen Deep-Copy-Ansatz verwenden möchten, werden in diesem Artikel mehrere andere aufgelistet. Ich würde daher empfehlen, nicht zu versuchen, einen eigenen zu schreiben.
quelle
Sie können dies ziemlich einfach tun;
quelle
Ich denke, dass der Code, den Sie suchen, ist:
Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)
quelle
Alternativ zum Kopieren der Daten können Sie einen Wrapper erstellen, mit dem Sie auf einen Teil des ursprünglichen Arrays zugreifen können, als wäre es eine Kopie des Teils des Arrays. Der Vorteil ist, dass Sie keine weitere Kopie der Daten im Speicher erhalten und der Nachteil ein leichter Aufwand beim Zugriff auf die Daten ist.
Verwendungszweck:
quelle
Array.ConstrainedCopy funktioniert.
quelle
Es gibt keine einzige Methode, die das tut, was Sie wollen. Sie müssen eine Klonmethode für die Klasse in Ihrem Array verfügbar machen. Wenn dann LINQ eine Option ist:
quelle
Wie wäre es mit Array.ConstrainedCopy :
Unten ist mein ursprünglicher Beitrag. Es wird nicht funktionieren
Sie könnten Array.CopyTo verwenden :
quelle
Wie wäre es damit:
Sie müssen dann die ICloneable-Schnittstelle für alle Klassen implementieren, für die Sie diese verwenden müssen, aber das sollte es tun.
quelle
Ich bin mir nicht sicher, wie tief es wirklich ist, aber:
MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()
Es ist ein bisschen Overhead, aber es könnte eine unnötige Methode ausschließen.
quelle
C # 8 hat eine Funktion namens Range bereitgestellt, mit der der Subarry vom Anfangs- bis zum Endindex abgerufen werden kann. Sie können es so verwenden.
quelle
Was das Klonen angeht, glaube ich nicht, dass die Serialisierung Ihre Konstruktoren aufruft. Dies kann Klasseninvarianten brechen, wenn Sie interessante Dinge im Ctor tun.
Es scheint, dass die sicherere Wette virtuelle Klonmethoden sind, die Kopierkonstruktoren aufrufen.
quelle
Das Klonen von Elementen in einem Array ist nicht universell möglich. Möchten Sie ein tiefes Klonen oder eine einfache Kopie aller Mitglieder?
Gehen wir zum "Best Effort" -Ansatz über: Klonen von Objekten mithilfe der ICloneable-Schnittstelle oder der binären Serialisierung:
Dies ist keine perfekte Lösung, da es einfach keine gibt, die für jeden Objekttyp geeignet ist.
quelle
Sie können an einem Kurs von Microsoft teilnehmen:
und dann
quelle
Ich fand, dass dies der optimale Weg ist, dies zu tun:
Ich hoffe es hilft!
quelle
Erweiterungsmethode verwenden:
und du kannst es benutzen
quelle
Code aus der System.Private.CoreLib.dll:
quelle
Es erfüllt nicht Ihre Klonanforderungen, aber es scheint einfacher als viele Antworten zu sein:
quelle
quelle