В чем разница между методами Clone и CopyTo для массивов в C#?

«В чем разница между методами Clone и CopyTo для массивов в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Критерий Clone() (метод экземпляра, объявлен в System.Array) CopyTo() (метод экземпляра, объявлен в System.Array и System.Collections.ICollection)
Назначение Создание новой копии всего массива (или многомерного массива). Копирование элементов в уже существующий целевой массив.
Возвращаемое значение Возвращает новый объект (object), который необходимо привести к типу массива. Не возвращает значения (void).
Целевой объект Создает целевой массив внутри метода. Целевой массив должен быть создан и передан в метод.
Гибкость Копирует весь массив целиком. Позволяет указать начальный индекс в целевом массиве, с которого начнется копирование.
Поверхностное/Глубокое копирование Для массивов значимых типов (int, struct) — глубокая копия значений. Для массивов ссылочных типов — поверхностная копия (копируются ссылки, а не объекты). Аналогично Clone() — поверхностное копирование.

Примеры:

// Исходный массив
int[] sourceArray = { 1, 2, 3, 4, 5 };

// 1. Использование Clone()
int[] clonedArray = (int[])sourceArray.Clone(); // Создается новый массив
clonedArray[0] = 99;
Console.WriteLine(sourceArray[0]); // Вывод: 1 (исходный массив не изменился)

// 2. Использование CopyTo()
int[] targetArray = new int[7]; // Целевой массив должен существовать
sourceArray.CopyTo(targetArray, 2); // Копируем, начиная с индекса 2 в целевом массиве
// targetArray теперь: [0, 0, 1, 2, 3, 4, 5]

// 3. Разница для ссылочных типов (поверхностное копирование)
Person[] people = { new Person("Alice") };
Person[] clonedPeople = (Person[])people.Clone();
clonedPeople[0].Name = "Bob";
Console.WriteLine(people[0].Name); // Вывод: "Bob"! Оба массива ссылаются на один объект.

Когда что использовать:

  • Используйте Clone(), когда вам нужна полная, независимая копия всего массива.
  • Используйте CopyTo() или Array.Copy(), когда вам нужно заполнить часть существующего массива или скопировать данные между массивами разной длины с указанием смещения.