Разница между System.Array.CopyTo () и System.Array.Clone ()

c# .net arrays .net-2.0

91109 просмотра

12 ответа

Какая разница между System.Array.CopyTo()и System.Array.Clone()?

Автор: Mister Dev Источник Размещён: 17.07.2019 12:33

Ответы (12)


47 плюса

Решение

Метод 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.
Редактировать:

Удалить неправильный пример.

Автор: Patrick Desjardins Размещён: 13.10.2008 06:20

25 плюса

Еще одно различие, не упомянутое до сих пор, состоит в том, что

  • с Clone()целевым массивом еще не должно существовать, так как новый создается с нуля.
  • с CopyTo()не только нужен массив назначения уже существует, он должен быть достаточно большим , чтобы вместить все элементы в исходном массиве из индекса вы указываете в качестве пункта назначения.
Автор: Michael Burr Размещён: 13.10.2008 06:45

21 плюса

Оба выполняют мелкие копии, как сказал @PatrickDesjardins (несмотря на то, что многие заблуждающиеся души думают, что CopyToэто глубокая копия).

Тем не менее, CopyToпозволяет скопировать один массив в указанный индекс в массиве назначения, что дает ему значительно большую гибкость.

Автор: FlySwat Размещён: 13.10.2008 06:23

18 плюса

Как указано во многих других ответах, оба метода выполняют поверхностные копии массива. Однако есть различия и рекомендации, которые еще не были учтены и выделены в следующих списках.

Характеристики System.Array.Clone:

  • Тесты, использующие .NET 4.0, показывают, что он медленнее, чем,CopyTo вероятно, потому что он использует Object.MemberwiseClone;
  • Требуется приведение результата к соответствующему типу;
  • Полученный массив имеет ту же длину, что и исходный.

Характеристики System.Array.CopyTo:

  • Быстрее, чемClone при копировании в массив того же типа;
  • Он вызывает в Array.Copyнаследовании возможности , являясь наиболее полезными:
    • Может вставлять элементы типа значения в элементы ссылочного типа, например, копируя int[]массив в object[];
    • Может распаковывать элементы ссылочного типа в элементы типа значения, например, копируя object[]массив в штучной упаковке intв int[];
    • Может выполнять расширенные преобразования для типов значений, например, копируя int[]в long[].
    • Может понижать элементы, например, копируя Stream[]массив в MemoryStream[](если какой-либо элемент в исходном массиве не может быть преобразован в MemoryStreamисключение, выбрасывается).
  • Позволяет скопировать источник в целевой массив, длина которого больше, чем у источника.

Также обратите внимание, что эти методы доступны для поддержки ICloneableи ICollection, поэтому, если вы имеете дело с переменными типов массивов, вы не должны использовать Cloneили CopyToи вместо этого использовать Array.Copyили Array.ConstrainedCopy. Ограниченная копия гарантирует, что если операция копирования не может завершиться успешно, то состояние целевого массива не будет повреждено.

Автор: João Angelo Размещён: 27.08.2012 12:12

7 плюса

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"

источник

Автор: GenZiy Размещён: 06.11.2009 08:10

2 плюса

Оба 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 ()) будет сделана до первого (верхнего) уровня. Но нижний уровень не копируется. Если нам также нужна копия более низкого уровня, мы должны сделать это явно. Вот почему после клонирования или копирования элементов ссылочного типа каждый элемент в массиве Cloned или Copied ссылается на ту же область памяти, на которую ссылается соответствующий элемент в исходном массиве. Это ясно указывает на то, что для нижнего уровня не создается отдельный экземпляр. И если бы это было так, то изменение значения любого элемента в массиве Копированный или Клонированный не имело бы эффекта в соответствующем элементе исходного массива.

Я думаю, что мое объяснение является исчерпывающим, но я не нашел другого способа сделать его понятным.

Автор: Prasad Размещён: 14.03.2011 07:31

0 плюса

Clone()Метод не дает ссылку на целевом экземпляр просто дать вам копию. то CopyTo()метод копирует элементы в существующий экземпляр.

Оба не дают ссылку на целевой экземпляр, и как многие участники говорят, что они дают мелкую копию (иллюзию) без ссылки, это ключ.

Автор: Mohammad Ahmed Размещён: 29.02.2012 11:19

0 плюса

Ответы сбивают меня с толку. Когда вы говорите мелкую копию, это означает, что они все еще указывают на один и тот же адрес. Это означает, что изменение одного из них также изменит другое.

Так что, если у меня есть A = [1,2,3,4], и я клонирую его и получаю B = [1,2,3,4]. Теперь, если я изменю B [0] = 9. Это означает, что теперь A будет A = [9,2,3,4]. Это верно?

Автор: Stranger Размещён: 09.06.2013 05:21

0 плюса

Обе мелкие копии. Метод 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 */
Автор: Nikhil Redij Размещён: 13.04.2017 02:50

0 плюса

Array.CopyTo не требует наличия целевого / целевого массива при вызове функции, тогда как Array.CopyTo требует целевого массива и индекса.

Автор: Aikansh Mann Размещён: 17.07.2019 09:33

-1 плюса

Clone() используется для копирования только структуры данных / массива, но не копирует фактические данные.

CopyTo() копирует структуру, а также фактические данные.

Автор: user257390 Размещён: 23.01.2010 12:49

-2 плюса

Обратите внимание: есть разница между использованием String [] и StringBuilder [].

В String - если вы измените String, другие скопированные нами массивы (с помощью CopyTo или Clone), которые указывают на одну и ту же строку, не изменятся, однако исходный массив String будет указывать на новую строку, однако, если мы используем StringBuilder в массиве указатель String не изменится, поэтому он повлияет на все копии, которые мы сделали для этого массива. Например:

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
}
Автор: inbaly Размещён: 09.12.2013 12:06
Вопросы из категории :
32x32