it-swarm.com.de

Unterschied zwischen System.Array.CopyTo () und System.Array.Clone ()

Was ist der Unterschied zwischen System.Array.CopyTo() und System.Array.Clone()?

72
Mister Dev

Die Methode Clone () gibt ein neues Array-Objekt (eine flache Kopie) zurück, das alle Elemente des ursprünglichen Arrays enthält. Die Methode CopyTo () kopiert die Elemente in ein anderes vorhandenes Array. Beide führen eine flache Kopie durch. Eine flache Kopie bedeutet, dass der Inhalt (jedes Array-Element) Verweise auf dasselbe Objekt wie die Elemente im ursprünglichen Array enthält. Eine tiefe Kopie (die von keiner dieser Methoden ausgeführt wird) erstellt eine neue Instanz des Objekts jedes Elements, was zu einem anderen, jedoch identischen Objekt führt.

Der Unterschied ist also:

1- CopyTo require to have a destination array when Clone return a new array.
2- CopyTo let you specify an index (if required) to the destination array.

Entfernen Sie das falsche Beispiel.

47

Ein weiterer, bisher nicht genannter Unterschied ist der

  • mit Clone() muss das Ziel-Array noch nicht existieren, da ein neues Array von Grund auf erstellt wird.
  • mit CopyTo() muss nicht nur das Ziel-Array bereits vorhanden sein, es muss auch groß genug sein, um alle Elemente des Quell-Arrays aus dem von Ihnen als Ziel angegebenen Index aufzunehmen.
25
Michael Burr

Beide führen flache Kopien durch, wie @PatrickDesjardins sagte (trotz der vielen irregeführten Seelen, die denken, dass CopyTo eine tiefe Kopie macht).

Mit CopyTo können Sie jedoch ein Array in einen angegebenen Index im Ziel-Array kopieren, wodurch die Flexibilität erheblich erhöht wird.

21
FlySwat

Wie in vielen anderen Antworten angegeben, führen beide Methoden flache Kopien des Arrays aus. Es gibt jedoch Unterschiede und Empfehlungen, die noch nicht angesprochen wurden und in den folgenden Listen hervorgehoben sind.

Eigenschaften von System.Array.Clone :

  • Tests mit .NET 4.0 haben gezeigt, dass es langsamer ist als CopyTo, wahrscheinlich weil es Object.MemberwiseClone ;
  • Erfordert das Umwandeln des Ergebnisses in den entsprechenden Typ;
  • Das resultierende Array hat die gleiche Länge wie die Quelle.

Eigenschaften von System.Array.CopyTo :

  • Ist schneller als Clone beim Kopieren in ein Array desselben Typs;
  • Es ruft Array.Copy auf, wobei das Erben von Fähigkeiten die nützlichsten sind:
    • Kann Elemente vom Typ "Wert" in Elemente vom Typ "Referenz" einschließen, z. B. indem ein Array int[] In ein Array object[] Kopiert wird.
    • Kann Referenztypelemente in Werttypelemente entpacken, z. B. indem ein object[] - Array von int in ein int[] Kopiert wird;
    • Kann erweiterte Konvertierungen für Werttypen durchführen, z. B. das Kopieren eines int[] In einen long[].
    • Kann Elemente heruntertragen, indem beispielsweise ein Array Stream[] In ein Array MemoryStream[] Kopiert wird (wenn ein Element im Quell-Array nicht in MemoryStream konvertiert werden kann, wird eine Ausnahme ausgelöst).
  • Ermöglicht das Kopieren der Quelle in ein Ziel-Array, dessen Länge größer als die der Quelle ist.

Beachten Sie auch, dass diese Methoden zur Unterstützung von ICloneable und ICollection bereitgestellt werden. Wenn Sie also mit Variablen von Array-Typen arbeiten, sollten Sie dies tun Verwenden Sie nicht Clone oder CopyTo und verwenden Sie stattdessen Array.Copy oder Array.ConstrainedCopy . Die eingeschränkte Kopie stellt sicher, dass der Zielarraystatus nicht beschädigt wird, wenn der Kopiervorgang nicht erfolgreich abgeschlossen werden kann.

18
João Angelo
object[] myarray = new object[] { "one", 2, "three", 4, "really big number", 2324573984927361 };

//create shallow copy by CopyTo
//You have to instantiate your new array first
object[] myarray2 = new object[myarray.Length];
//but then you can specify how many members of original array you would like to copy 
myarray.CopyTo(myarray2, 0);

//create shallow copy by Clone
object[] myarray1;
//here you don't need to instantiate array, 
//but all elements of the original array will be copied
myarray1 = myarray.Clone() as object[];

//if not sure that we create a shalow copy lets test it
myarray[0] = 0;
Console.WriteLine(myarray[0]);// print 0
Console.WriteLine(myarray1[0]);//print "one"
Console.WriteLine(myarray2[0]);//print "one"

die Quelle

7
GenZiy

Sowohl CopyTo () als auch Clone () erstellen eine flache Kopie. Mit der Methode Clone () wird ein Klon des ursprünglichen Arrays erstellt. Es wird ein Array mit exakter Länge zurückgegeben.

Andererseits kopiert CopyTo () die Elemente aus dem ursprünglichen Array in das Ziel-Array, beginnend mit dem angegebenen Ziel-Array-Index. Beachten Sie, dass dadurch einem bereits vorhandenen Array Elemente hinzugefügt werden.

Der folgende Code widerspricht den Postings, die besagen, dass CopyTo () eine tiefe Kopie erstellt:

public class Test
{
public string s;
}

// Write Main() method and within it call test()

private void test()
{
Test[] array = new Test[1];
array[0] = new Test();
array[0].s = "ORIGINAL";

Test[] copy = new Test[1];
array.CopyTo(copy, 0);

// Next line displays "ORIGINAL"
MessageBox.Show("array[0].s = " + array[0].s);
copy[0].s = "CHANGED";

// Next line displays "CHANGED", showing that
// changing the copy also changes the original.
MessageBox.Show("array[0].s = " + array[0].s);
}

Lass es mich ein bisschen erklären. Wenn es sich bei den Elementen des Arrays um Referenztypen handelt, wird die Kopie (sowohl für Clone () als auch für CopyTo ()) bis zur ersten (obersten) Ebene erstellt. Die untere Ebene wird jedoch nicht kopiert. Wenn wir auch eine Kopie einer niedrigeren Ebene benötigen, müssen wir dies explizit tun. Aus diesem Grund verweist jedes Element im geklonten oder kopierten Array nach dem Klonen oder Kopieren von Elementen des Referenztyps auf denselben Speicherort, auf den das entsprechende Element im ursprünglichen Array verweist. Dies zeigt deutlich an, dass keine separate Instanz für eine niedrigere Ebene erstellt wurde. Wenn dies der Fall wäre, hätte eine Änderung des Werts eines Elements im kopierten oder geklonten Array keine Auswirkungen auf das entsprechende Element des ursprünglichen Arrays.

Ich denke, meine Erklärung ist erschöpfend, aber ich habe keine andere Möglichkeit gefunden, sie verständlich zu machen.

2
Prasad

Array.Clone erfordert nicht, dass ein Ziel-/Zielarray verfügbar ist, wenn die Funktion aufgerufen wird, während Array.CopyTo ein Zielarray und einen Index erfordert.

0
Aikansh Mann

Die Clone() -Methode verweist nicht auf die Zielinstanz, sondern gibt Ihnen nur eine Kopie. Die Methode CopyTo() kopiert die Elemente in eine vorhandene Instanz.

Beide geben nicht die Referenz der Zielinstanz an und so viele Mitglieder sagen, dass sie eine flache Kopie (Illusionskopie) ohne Referenz geben, ist dies der Schlüssel.

0
Mohammad Ahmed

Beide sind flache Kopien. CopyTo-Methode ist keine tiefe Kopie. Überprüfen Sie den folgenden Code:

public class TestClass1
{
    public string a = "test1";
}

public static void ArrayCopyClone()
{
    TestClass1 tc1 = new TestClass1();
    TestClass1 tc2 = new TestClass1();

    TestClass1[] arrtest1 = { tc1, tc2 };
    TestClass1[] arrtest2 = new TestClass1[arrtest1.Length];
    TestClass1[] arrtest3 = new TestClass1[arrtest1.Length];

    arrtest1.CopyTo(arrtest2, 0);
    arrtest3 = arrtest1.Clone() as TestClass1[];

    Console.WriteLine(arrtest1[0].a);
    Console.WriteLine(arrtest2[0].a);
    Console.WriteLine(arrtest3[0].a);

    arrtest1[0].a = "new";

    Console.WriteLine(arrtest1[0].a);
    Console.WriteLine(arrtest2[0].a);
    Console.WriteLine(arrtest3[0].a);
}

/* Output is 
test1
test1
test1
new
new
new */
0
Nikhil Redij

Die Antworten verwirren mich. Wenn Sie flache Kopie sagen, bedeutet dies, dass sie immer noch auf dieselbe Adresse verweisen. Das heißt, wenn Sie eines von beiden ändern, ändert sich auch das andere.

Wenn ich also A = [1,2,3,4] habe und es klone, erhalte ich B = [1,2,3,4]. Wenn ich nun B [0] = 9 ändere, bedeutet dies, dass A jetzt A = [9,2,3,4] ist. Ist das korrekt?

0
Stranger