93 votes

Différence entre System.Array.CopyTo() et System.Array.Clone()

Quelle est la différence entre le System.Array.CopyTo() y System.Array.Clone() ?

37 votes

C'est une question d'entretien un peu stupide. "Je ne m'en souviens pas, laissez-moi vérifier la documentation..."

0 votes

@MisterDev Aucune de ces méthodes ne conservera de référence au tableau original à partir duquel vous avez copié, non.

0 votes

@Nyerguds Je pense qu'il voulait dire qu'ils gardent tous les deux des références aux objets éléments du tableau original, pas à l'objet tableau original lui-même.

73voto

Patrick Desjardins Points 51478

El Clone() renvoie un nouvel objet tableau (une copie superficielle) contenant tous les éléments du tableau original. L'adresse CopyTo() copie les éléments dans un autre tableau existant. Les deux méthodes effectuent une copie superficielle. Une copie superficielle signifie que le contenu (chaque élément du tableau) contient des références au même objet que les éléments du tableau d'origine. Une copie profonde (qu'aucune de ces méthodes n'effectue) créerait une nouvelle instance de l'objet de chaque élément, ce qui donnerait un objet différent, mais identique.

Les différences sont donc :

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.

Edit :

Supprimez le mauvais exemple.

7 votes

Votre exemple est faux. Dans le premier, numbersCopy est juste une autre référence au tableau assigné à numbers . C'est no la même chose qu'en utilisant le CopyTo() méthode. Si vous utilisez CopyTo() vous obtiendrez les mêmes résultats que ceux obtenus dans votre Clone() exemple. De plus, c'est du C# - System.out.println devrait être Console.WriteLine .

6 votes

Cette réponse, qui est trompeur comme d'autres l'ont dit, c'est un copier-coller d'ici : geekswithblogs.net/dforhan/archive/2005/12/01/61852.aspx

0 votes

Selon l'exemple de GenZiy, les deux sont des copies superficielles. Une copie superficielle d'un tableau ne copie que les éléments du tableau, qu'ils soient de type référence ou valeur, mais elle ne copie pas les objets auxquels les références font référence. Les références du nouveau tableau pointent vers les mêmes objets que les références du tableau d'origine. En revanche, une copie profonde d'un tableau copie les éléments et tout ce qui est directement ou indirectement référencé par les éléments. msdn.microsoft.com/fr/us/library/system.array.clone.aspx

32voto

Michael Burr Points 181287

Une autre différence non mentionnée jusqu'à présent est que

  • avec Clone() le tableau de destination n'a pas besoin d'exister encore puisqu'un nouveau tableau est créé à partir de zéro.
  • avec CopyTo() non seulement le tableau de destination doit déjà exister, mais il doit être suffisamment grand pour contenir tous les éléments du tableau source à partir de l'index que vous spécifiez comme destination.

27voto

João Angelo Points 24422

Comme indiqué dans de nombreuses autres réponses, les deux méthodes fonctionnent copies superficielles du tableau. Cependant, il existe des différences et des recommandations qui n'ont pas encore été abordées et qui sont mises en évidence dans les listes suivantes.

Caractéristiques de System.Array.Clone :

  • Les tests, effectués avec .NET 4.0, montrent qu'elle est plus lent que CopyTo probablement parce qu'il utilise Object.MemberwiseClone ;
  • Nécessite de couler le résultat au type approprié ;
  • Le tableau résultant a la même longueur que la source.

Caractéristiques de System.Array.CopyTo :

  • Est plus rapide que Clone lors de la copie dans un tableau du même type ;
  • Elle fait appel à Array.Copy hériter est une capacité étant les plus utiles :
    • Peut mettre en boîte des éléments de type valeur dans des éléments de type référence, par exemple, en copiant une int[] dans un tableau object[] ;
    • Peut décomposer les éléments de type référence en éléments de type valeur, par exemple, en copiant une object[] réseau de boîtes int dans un int[] ;
    • Peut effectuer des conversions d'élargissement sur les types de valeur, par exemple, en copiant un int[] en un long[] .
    • Les éléments descendants peuvent-ils, par exemple, copier une Stream[] dans un tableau MemoryStream[] (si un élément du tableau source n'est pas convertible en MemoryStream une exception est levée).
  • Permet de copier la source vers un tableau cible dont la longueur est supérieure à celle de la source.

Notez également que ces méthodes sont mises à disposition pour soutenir ICloneable y ICollection Ainsi, si vous traitez des variables de type tableau, vous ne devez pas utiliser la fonction Clone o CopyTo et utiliser à la place Array.Copy o Array.ConstrainedCopy . La copie sous contrainte garantit que si l'opération de copie ne peut pas se terminer avec succès, l'état du tableau cible n'est pas corrompu.

0 votes

C'est une information solide. Alors pourquoi ne pas écrire une version plus rapide et générique de Clone ? Quelque chose comme : Ex : public static T[] ExtFastClone<T>(this T[] arr) { if (null == arr) { return null ; } T[] arr2 = new T[arr.Length] ; arr.CopyTo(arr2, 0) ; return arr2 ; } Ou vous pourriez faire une version de casting (pour permettre int -> long) comme : public static TOut[] ExtFastClone<TIn, TOut>(this TIn[] arr)

0 votes

Pour un clonage superficiel sur .Net 3.5 ou plus, vous pouvez simplement utiliser la méthode Linq. .ToArray() méthode. Elle fait une copie de toute façon, et elle peut être exécutée sur n'importe quelle IEnumerable<> y compris les réseaux. Et contrairement à .Clone() il est tapé, donc pas de casting nécessaire.

23voto

FlySwat Points 61945

Les deux effectuent des copies superficielles comme l'a dit @PatrickDesjardins (malgré les nombreuses âmes égarées qui pensent que CopyTo fait une copie profonde).

Cependant, CopyTo vous permet de copier un tableau vers un index spécifié dans le tableau de destination, ce qui lui donne beaucoup plus de flexibilité.

8voto

GenZiy Points 294
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"

la source

1 votes

Je suppose que le terme "shalow copy" signifie que seules les références sont copiées, pas la valeur. Ainsi, si vous changez la valeur de myarray[0] de "un" à 0, la valeur de myarray1[0] et myarray[1] ne devrait-elle pas également être 0.

1 votes

Désolé, mais votre supposition est fausse. La copie superficielle n'est pas une copie de références : "La méthode MemberwiseClone crée une copie superficielle en créant un nouvel objet, puis en copiant les champs non statiques de l'objet actuel vers le nouvel objet." voir msdn.microsoft.com/fr/us/library/

2 votes

La copie superficielle ou profonde est sans importance si les types que vous mettez dans votre tableau sont primitifs/immuables . Chaînes de caractères et nombres entiers siempre produisent une nouvelle copie quand ils sont mis dans quelque chose d'autre. Pour tester la copie profonde, placez un objet complexe (comme un tableau) sur l'un des points.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X