Разница между системой.Матрица.CopyTo() и система.Матрица.Клон()
в чем разница между System.Array.CopyTo()
и System.Array.Clone()
?
11 ответов:
на Clone () метод возвращает новый массив (поверхностное копирование) объект, содержащий все элементы в исходном массиве. Элемент CopyTo () метод копирует элементы в другой массив. Выполнять мелкую копию. Неглубокая копия означает, что содержимое (каждый элемент массива) содержит ссылки на тот же объект, что и элементы в исходном массиве. Глубокая копия (которую ни один из этих методов не выполняет) создаст новый экземпляр объекта каждого элемента, в результате чего другой, но идентичный объект.
Так что разница есть :
Редактировать: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.
удалить неправильный пример.
еще одно отличие, не упомянутое до сих пор, заключается в том, что
- С
Clone()
целевой массив еще не должен существовать, так как новый создается с нуля.- С
CopyTo()
мало того, что целевой массив должен уже существовать, он должен быть достаточно большим, чтобы содержать все элементы в исходном массиве из индекса, указанного в качестве целевого.
оба выполняют мелкие копии, как сказал @PatrickDesjardins (несмотря на многие обманутые души, которые думают, что
CopyTo
делает глубокую копию).однако,
CopyTo
позволяет скопировать один массив в указанный индекс в целевом массиве, что дает ему значительно большую гибкость.
как указано во многих других ответах, оба метода выполняют неглубокое копии массива. Однако существуют различия и рекомендации, которые еще не были рассмотрены и которые выделены в следующих списках.
характеристики
System.Array.Clone
:
- тесты, использующие .NET 4.0, показывают, что это медленнее, чем
CopyTo
наверное, потому, что он используетObject.MemberwiseClone
;- требует приведения результата к соответствующему типу;
- результирующий массив имеет ту же длину, что и исходный.
характеристики
System.Array.CopyTo
:
- быстрее
Clone
при копировании в массив такого же типа;- он звонит в
Array.Copy
наследование-это возможности, будучи наиболее полезные:
- можно поместить элементы типа значения в элементы ссылочного типа, например, скопировав
int[]
массив вobject[]
;- можно распаковать элементы ссылочного типа В тип параметра, например, для копирования
object[]
массив в штучной упаковкеint
наint[]
;- может выполнять расширяющие преобразования для типов значений, например, копирование a
int[]
наlong[]
.- можно понизить элементы, например, копирование a
Stream[]
массив вMemoryStream[]
(если какой-либо элемент в исходном массиве не преобразуется вMemoryStream
исключение).- позволяет скопировать источник в целевой массив, длина которого больше длины источника.
Также обратите внимание, что эти методы доступны для поддержки
ICloneable
иICollection
, так что если вы имеете дело с переменными типа массив, вы не должны использоватьClone
илиCopyTo
и вместо использованияArray.Copy
илиArray.ConstrainedCopy
. Ограниченная копия гарантирует, что если операция копирования не может завершиться успешно, то состояние целевого массива не повреждено.
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"
и CopyTo() и Clone () делают мелкую копию. Метод clone() создает копию исходного массива. Он возвращает точный массив длины.
С другой стороны, CopyTo() копирует элементы из исходного массива в целевой массив, начиная с указанного индекса целевого массива. Обратите внимание, что это добавляет элементы в уже существующий массив.
следующий код будет противоречить сообщениям о том, что CopyTo () делает глубокий копия:
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); }
позвольте мне объяснить это немного. Если элементы массива имеют ссылочные типы, то копия (как для Clone (), так и для CopyTo ()) будет составлена до первого (верхнего) уровня. Но нижний уровень не копируется. Если нам также нужна копия более низкого уровня, мы должны сделать это явно. Вот почему после клонирования или копирования элементов ссылочного типа каждый элемент в клонированном или скопированном массиве ссылается на ту же ячейку памяти, на которую ссылается соответствующий элемент в исходный массив. Это ясно указывает на то, что для более низкого уровня не создается отдельный экземпляр. И если бы это было так, то изменение значения любого элемента в скопированном или клонированном массиве не имело бы эффекта в соответствующем элементе исходного массива.
Я думаю, что мое объяснение является исчерпывающим, но я не нашел другого способа, чтобы сделать ее понятной.
The
Clone()
метод не дает ссылку на целевой экземпляр просто дать вам копию. элементCopyTo()
метод копирует элементы в существующий экземпляр.оба не дают ссылку на целевой экземпляр, и поскольку многие члены говорят, что они дают мелкую копию (иллюзорную копию) без ссылки, это ключ.
ответы сбивают меня с толку. Когда вы говорите "мелкая копия", это означает, что они все еще указывают на один и тот же адрес. Это означает, что изменение одного из них также изменит другого.
Так что если у меня есть A = [1,2,3,4] и я клонирую его и получаю B = [1,2,3,4]. Теперь, если я изменю B[0] = 9. Это означает, что A теперь будет a = [9,2,3,4]. Это правильно?
оба являются мелкими копиями. метод CopyTo не является глубокой копией. Проверьте следующий код :
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 */
Clone()
используется для копирования только структуры данных / массива он не копирует фактические данные.
CopyTo()
копирует структуру, а также фактические данные.
обратите внимание: существует разница между использованием String[] для StringBuilder[].
в строке - если вы измените строку, в других массивах, то есть копируется (копирование, чтобы купить или Клон), который указывает на ту же строку не изменится, но исходный массив строк будет указывать на новую строку, однако, если использовать StringBuilder в массив, строка, указатель не изменяется, следовательно, он будет влиять на все экземпляры мы добились за это время. Например:
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 }