[ Полезный рекламный блок ]
Попробуйте свои силы в игре, где ваши навыки программирования на C# станут решающим фактором. Переходите по ссылке 🔰.
У C# клонування об’єкта означає створення його копії. Однак існує два типи клонування: неглибоке клонування і глибоке клонування.
Під час неглибокого клонування створюється новий об’єкт, який є копією вихідного об’єкта, але вміст копії, як і раніше, вказує на ті самі об’єкти, що й оригінал. Це означає, що зміни, внесені у властивості копії, також вплинуть на оригінал.
Глибоке клонування, з іншого боку, створює новий об’єкт, який є копією оригіналу, але вміст копії також копіюється, тому два об’єкти не мають спільних посилань. Це означає, що зміни, внесені у властивості копії, не вплинуть на оригінал.
У C# існує кілька способів глибокого клонування об’єкта, включно з реалізацією інтерфейсу ICloneable, використанням серіалізації та десеріалізації, а також використанням сторонніх бібліотек, таких як AutoMapper, Newtonsoft.Json або BinaryFormatter.
Серіалізації та десеріалізація
Один із поширених підходів – використання серіалізації та десеріалізації. Ось приклад:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable] public class MyClass {     public int Number { get; set; }     public string Text { get; set; } } class Program {     static void Main(string[] args)     {         MyClass original = new MyClass { Number = 42, Text = "Hello, World!" };         // Create a memory stream and binary formatter         MemoryStream stream = new MemoryStream();         BinaryFormatter formatter = new BinaryFormatter();         // Serialize the object to the memory stream         formatter.Serialize(stream, original);         // Reset the stream position to the beginning         stream.Position = 0;         // Deserialize the object from the memory stream         MyClass copy = (MyClass)formatter.Deserialize(stream);         // Modify the copy's properties         copy.Number = 24;         copy.Text = "Goodbye, World!";         // The original's properties remain unchanged         Console.WriteLine(original.Number); // Output: 42         Console.WriteLine(original.Text); // Output: Hello, World!         // The copy's properties have been modified         Console.WriteLine(copy.Number); // Output: 24         Console.WriteLine(copy.Text); // Output: Goodbye, World!     } } | 
У цьому прикладі ми визначаємо простий клас MyClass, який має дві властивості: Number і Text. Потім ми створюємо екземпляр MyClass і серіалізуємо його в потік пам’яті за допомогою BinaryFormatter. Ми скидаємо позицію потоку на початок, а потім десеріалізуємо об’єкт назад у новий екземпляр MyClass під назвою copy. Нарешті, ми змінюємо властивості копії та перевіряємо, що властивості оригіналу залишилися незмінними.
Використання серіалізації та десеріалізації передбачає серіалізацію вихідного об’єкта в потік байтів, а потім його десеріалізацію назад у новий об’єкт. Цей підхід може бути повільнішим, ніж інші методи, але він часто простіший у реалізації.
Реалізація інтерфейсу ICloneable
Для початку розглянемо приклад не глибокого клонування:
| 1 2 3 4 5 6 7 8 9 | class Person : ICloneable     {         public string Name { get; set; }         public int Age { get; set; }         public object Clone()         {             return new Person { Name = this.Name, Age = this.Age };         }     } | 
Використання:
| 1 2 3 4 5 6 7 | static void Main()         {             Person p1 = new Person { Name = "Tom", Age = 23 };             Person p2 = (Person)p1.Clone();             p2.Name = "Alice";             Console.WriteLine(p1.Name); // Tom         } | 
Тепер приклад із глибоким клонуванням:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Person : ICloneable     {         public string Name { get; set; }         public int Age { get; set; }         public Company Work { get; set; }         public object Clone()         {             Company company = new Company { Name = this.Work.Name };             return new Person             {                 Name = this.Name,                 Age = this.Age,                 Work = company             };         }     } | 
Або можна зробити так:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Person : ICloneable     {         public string Name { get; set; }         public int Age { get; set; }         public Company Work { get; set; }         public object Clone()         {             var person = (Person)this.MemberwiseClone();             person.Work = (Company)this.Work.Clone();             return person;         }     }     class Company:ICloneable     {         public string Name { get; set; }         public object Clone()         {             return this.MemberwiseClone();         }     } | 
Використання:
| 1 2 3 4 5 6 7 8 9 | static void Main(string[] args)         {             Person p1 = new Person { Name = "Tom", Age = 23, Work = new Company { Name = "Microsoft" } };             Person p2 = (Person)p1.Clone();             p2.Work.Name = "Google";             p2.Name = "Alice";             Console.WriteLine(p1.Name);             Console.WriteLine(p1.Work.Name);         } | 


 Завантаження...
Завантаження...






