Списки клонов и массивы объектов в C#
Это последнее сообщение, которое я напишу о клонах, по крайней мере на некоторое время. Некоторые классы коллекций уже могут создавать клоны. Например, массив может клонировать сам, хотя результат всегда является мелким клоном. В этом примере показано, как добавить методы расширения, которые позволяют массивам и спискам делать как мелкие, так и глубокие клоны.
В следующем коде показаны новые методы расширения. (Это упрощенные версии, основанные на комментарии ниже Э. Андерсона.)
// Возвращает глубокий клон списка. public static ListDeepClone (this List items) { var query = from T item in items select item.DeepClone(); return new List (query); } // Возвращаем глубокий клон массива. public static T[] DeepClone (this T[] items) { var query = from T item in items select item.DeepClone(); return query.ToArray(); } // Возвращаем неглубокий клон списка. public static List ShallowClone (this List items) { return new List (items); } // Возвращаем неглубокий клон массива. public static T[] ShallowClone (this T[] items) { return (T[])items.Clone(); }
Все эти методы являются общими, поэтому они принимают параметр типового типа T, который представляет тип объектов в списке или массиве.
Первый метод делает глубокий клон списка. Он создает запрос LINQ, который выполняет итерацию через элементы в списке и вызывает метод DeepClone для каждого. эта версия DeepClone описана в сообщении
Альтернативной стратегией будет требование, чтобы тип T реализовал ICloneable, а затем вызывается метод Clone объекта. К сожалению, метод Clone, требуемый ICloneable, не обязательно должен быть глубоким клоном, поэтому в некоторых случаях результат может быть мелким клоном.
Первый представленный здесь метод передает запрос LINQ в конструктор нового списка. Этот конструктор может принимать IEnumerable в качестве параметра и использовать его для создания элементов в новом списке.
Второй метод расширения похож на первый, за исключением того, что он работает для массива вместо списка. Он использует аналогичный запрос LINQ, а затем просто вызывает его метод ToArray для преобразования элементов, выбранных запросом в массив.
Третий метод делает мелкие клоны объектов в списке. Он передает исходный список в конструктор нового списка. Этот конструктор использует элементы для инициализации нового списка.