¿Cuál es la diferencia entre System.Array.CopyTo()
y System.Array.Clone()
?Diferencia entre System.Array.CopyTo() y System.Array.Clone()
Respuesta
El método Clone() devuelve un nuevo objeto de matriz (una copia superficial) que contiene todos los elementos en la matriz original. El método CopyTo() copia los elementos en otra matriz existente. Ambos realizan una copia superficial. Una copia superficial significa que el contenido (cada elemento de la matriz) contiene referencias al mismo objeto que los elementos en la matriz original. Una copia profunda (que ninguno de estos métodos realiza) crearía una nueva instancia del objeto de cada elemento, dando como resultado un objeto diferente pero idéntico.
Así que la diferencia son:
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.
Editar:
Retire el mal ejemplo.
Su ejemplo es incorrecto. En el primero, 'numbersCopy' es solo otra referencia a la matriz asignada a' numbers'. Esto * no * es lo mismo que usar el método 'CopyTo()'. Si usa 'CopyTo()', obtendrá los mismos resultados que en su ejemplo 'Clone()'. Además, esto es C# - 'System.out.println' debe ser' Console.WriteLine'. –
Como dijo @Graham, esto ni siquiera es código de C# ... – Mehrdad
Esta respuesta, que es ** engañosa ** como otro dicho es un copiar y pegar desde aquí: http://geekswithblogs.net/dforhan/archive/ 2005/12/01/61852.aspx – Mikhail
Ambos realizan copias superficiales como dijo @PatrickDesjardins (a pesar de las muchas almas engañadas que creen que CopyTo
hace una copia profunda).
Sin embargo, CopyTo
le permite copiar una matriz a un índice especificado en la matriz de destino, dándole una flexibilidad significativamente mayor.
Otra diferencia no mencionado hasta ahora es que
- con
Clone()
la matriz de destino no tiene por qué existir sin embargo, desde uno nuevo se crea a partir de cero. - con
CopyTo()
no solo es necesario que la matriz de destino exista ya, sino que debe ser lo suficientemente grande como para contener todos los elementos en la matriz de origen del índice que especifique como destino.
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"
Supongo que la copia shalow significa que solo se copian las referencias, no el valor. Entonces, si está cambiando el valor de myarray [0] de "uno" a 0, entonces el valor de myarray1 [0] y myarray [1] tampoco debería ser 0. –
Lo siento, pero su suposición es incorrecta.La copia superficial no es una copia de las referencias: "El método MemberwiseClone crea una copia superficial creando un nuevo objeto y luego copiando los campos no estáticos del objeto actual en el nuevo objeto". vea http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx – GenZiy
La copia poco profunda o profunda es irrelevante si los tipos que coloca en la matriz son primitivos/inmutables. Las cadenas y los enteros _siempre_ producen una nueva copia cuando se ponen en otra cosa. Para probar la copia profunda, coloque un objeto complejo (como una matriz) en uno de los puntos. – Nyerguds
Clone()
se utiliza para copiar única estructura de datos/array no copia los datos reales.
CopyTo()
copia la estructura y los datos reales.
Tanto CopyTo() y Clone() hacen una copia superficial. El método Clone() hace una copia de la matriz original. Devuelve una matriz de longitud exacta.
Por otro lado, CopyTo() copia los elementos de la matriz original a la matriz de destino comenzando en el índice de matriz de destino especificado. Tenga en cuenta que esto agrega elementos a una matriz ya existente.
El siguiente código estará en contradicción con los anuncios que dicen que CopyTo() hace una copia profunda:
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);
}
Voy a explicar un poco. Si los elementos de la matriz son de tipos de referencia, entonces la copia (tanto para Clone() como CopyTo()) se realizará hasta el primer nivel (superior). Pero el nivel inferior no se copia. Si también necesitamos una copia del nivel inferior, tenemos que hacerlo explícitamente. Es por eso que después de Clonación o Copia de elementos de tipo de referencia, cada elemento en la matriz Clonado o Copiado se refiere a la misma ubicación de memoria a la que hace referencia el elemento correspondiente en la matriz original.Esto indica claramente que no se crea una instancia separada para el nivel inferior. Y si fuera así, entonces cambiando el valor de cualquier elemento de la matriz copiada o clonada no tendría efecto en el elemento correspondiente de la matriz original.
creo que mi explicación es exhaustiva pero he encontrado ninguna otra manera para que sea comprensible.
El método Clone()
no dan referencia a la instancia de destino sólo le dará una copia. las copias CopyTo()
método los elementos en una instancia existente.
Ambos no dan la referencia de la instancia de destino y como muchos miembros dicen que dan una copia superficial (copia de ilusión) sin referencia, esta es la clave.
Como se indica en muchas otras respuestas ambos métodos realizan shallow copies de la matriz. Sin embargo, existen diferencias y recomendaciones que aún no se han abordado y que se destacan en las siguientes listas.
Características de System.Array.Clone
:
- pruebas, utilizando .NET 4.0, muestran que es más lento que
CopyTo
, probablemente debido a que utilizaObject.MemberwiseClone
; - Requiere arrojar el resultado al tipo apropiado;
- La matriz resultante tiene la misma longitud que la fuente.
Características de System.Array.CopyTo
:
- es más rápido que
Clone
cuando se copia al conjunto de mismo tipo; - Se pone en
Array.Copy
heredera es capacidades de, siendo los más útiles:- puede boxear elementos de tipo valor en elementos de tipo de referencia, por ejemplo, la copia de una matriz
int[]
en unobject[]
; - Puede unbox elementos de tipo de referencia en elementos de tipo de valor, por ejemplo, copiar una matriz
object[]
deint
en unint[]
; - Puede realizar conversiones de ampliación en tipos de valores, por ejemplo, copiando
int[]
enlong[]
. - Puede downcast elementos, por ejemplo, copiando una matriz
Stream[]
en unMemoryStream[]
(si cualquier elemento en la matriz fuente no es convertible aMemoryStream
se lanza una excepción).
- puede boxear elementos de tipo valor en elementos de tipo de referencia, por ejemplo, la copia de una matriz
- Permite copiar la fuente a una matriz de destino que tiene una longitud mayor que la fuente.
También tenga en cuenta, se ponen a disposición para apoyar ICloneable
y ICollection
estos métodos, por lo que si se trata de variables de tipos de matriz que no deben usar Clone
o CopyTo
y en su lugar utilizar Array.Copy
o Array.ConstrainedCopy
.La copia restringida asegura que si la operación de copia no se puede completar correctamente, entonces el estado de la matriz de destino no está dañado.
Esta es información sólida. Entonces, ¿por qué no escribimos una versión más rápida y genérica de Clone? Algo como: Ex: public static T [] ExtFastClone
Para la clonación superficial desnuda en .Net 3.5 o superior, puede simplemente usar ' .ToArray() 'método. De todos modos, hace una copia y puede ejecutarse en cualquier 'IEnumerable <>', incluidas las matrices. Y a diferencia de '.Clone()', está tipeado, por lo que no es necesario realizar un fundido. – Nyerguds
Las respuestas son confusas para mí. Cuando dice copia poco profunda, esto significa que todavía están apuntando a la misma dirección. Lo que significa que cambiar cualquiera de los dos cambiará también a otro.
Así que si tengo A = [1,2,3,4] y lo clono y obtengo B = [1,2,3,4]. Ahora, si cambio B [0] = 9. Esto significa que A ahora será A = [9,2,3,4]. ¿Es eso correcto?
no. si cambiamos el valor de b array, eso afecta solo a b array. no la matriz A. – Gomathipriya
Números enteros, cadenas, fechas, etc. _ nunca se copian por referencia, personas_. Poco profundo significa "solo un nivel profundo". Significa que los tipos _reference_ (matrices u otros objetos complejos) seguirán apuntando a los mismos objetos. No primitivos/tipos inmutables; aquellos están diseñados para nunca ser utilizados como referencias. – Nyerguds
Tenga en cuenta: Hay una diferencia entre el uso de String [] a StringBuilder [].
En Cadena: si cambia la Cadena, las otras matrices que hemos copiado (mediante Copia o Copia) que apuntan a la misma cadena no cambiarán, pero la matriz de Cadenas original apuntará a una nueva Cadena, sin embargo, si usamos un StringBuilder en una matriz, el puntero de cadena no cambiará, por lo tanto, afectará todas las copias que hemos hecho para esta matriz. Por ejemplo:
public void test()
{
StringBuilder[] sArrOr = new StringBuilder[1];
sArrOr[0] = new StringBuilder();
sArrOr[0].Append("hello");
StringBuilder[] sArrClone = (StringBuilder[])sArrOr.Clone();
StringBuilder[] sArrCopyTo = new StringBuilder[1];
sArrOr.CopyTo(sArrCopyTo,0);
sArrOr[0].Append(" world");
Console.WriteLine(sArrOr[0] + " " + sArrClone[0] + " " + sArrCopyTo[0]);
//Outputs: hello world hello world hello world
//Same result in int[] as using String[]
int[] iArrOr = new int[2];
iArrOr[0] = 0;
iArrOr[1] = 1;
int[] iArrCopyTo = new int[2];
iArrOr.CopyTo(iArrCopyTo,0);
int[] iArrClone = (int[])iArrOr.Clone();
iArrOr[0]++;
Console.WriteLine(iArrOr[0] + " " + iArrClone[0] + " " + iArrCopyTo[0]);
// Output: 1 0 0
}
Esto no está relacionado con 'CopyTo' vs' Clone'. Es semántica de referencia vs semántica de valores. int es un tipo de valor, por lo que se obtiene una nueva copia cada vez. StringBuilder tiene semántica de referencia, por lo que está actuando en la misma copia. – nawfal
@nawfal - Lo sé, esa fue la razón por la que escribí 'por favor, tenga en cuenta' ... hay una diferencia de comportamiento entre String, StringBuilder e int, en copiar y clonar, y puede ser confuso para alguien que no está enterado de eso. – inbaly
Ambas son copias superficiales. El método CopyTo no es una copia profunda. Verificar el siguiente código:
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 */
- 1. MySQL: diferencia entre ', `,' y"
- 2. Diferencia entre objeto y *?
- 3. Diferencia entre. y #
- 4. ¿Diferencia entre == y caso?
- 5. La diferencia entre $ * y $ @
- 6. Diferencia entre & y &
- 7. VBA: Diferencia entre y y +
- 8. Diferencia entre -Wconversion entre gcc y g ++
- 9. Diferencia entre subprocess.Popen y os.system
- 10. Diferencia entre decimal y decimal
- 11. ¿Diferencia entre trazo y relleno?
- 12. Diferencia entre interrupción y eventos
- 13. Diferencia entre netTcpContextBinding y netTcpBinding
- 14. ¿Diferencia entre brújula y sass?
- 15. Diferencia entre "__method__" y "método"
- 16. Diferencia entre Mealy y Moore
- 17. Diferencia entre HashSet y HashMap?
- 18. diferencia entre ajax y enviar
- 19. Diferencia entre sistema y shell_exec
- 20. Diferencia entre Style y ControlTemplate
- 21. Diferencia entre relativo y absoluto
- 22. Diferencia entre window.location.href y top.location.href
- 23. Diferencia entre strncpy y memcpy?
- 24. diferencia entre SDL y GLUT
- 25. Diferencia entre Javascript y PHP
- 26. Diferencia entre Session y HttpContext.Current.Session
- 27. diferencia entre px y em
- 28. Diferencia entre sqrtf y sqrtf
- 29. ¿Diferencia entre Keychain y NSUserDefault?
- 30. Diferencia entre ViewData y TempData?
clase de pregunta tonta entrevista. "No recuerdo de improviso, déjame revisar la documentación ..." –
@MisterDev Ninguno de estos mantendrá ninguna referencia a la matriz original de la que copiaste, no. – Nyerguds
@Nyerguds Creo que quiso decir que ambos mantienen referencias a los objetos del elemento de matriz original, no al objeto de matriz original en sí. – reirab