C# 建立物件的淺層複製(Shallow Clone/Copy)及深層複製(Deep Clone/Copy)
C# 建立物件的淺層複製(Shallow Clone/Copy)及深層複製(Deep Clone/Copy)
在C#中,物件的淺層複製(Shallow Copy)和深層複製(Deep Copy)是兩種不同的複製方式,它們在複製物件時的行為和結果有所不同。
淺層複製(Shallow Copy)
淺層複製是指創建一個新的物件,並將原物件的值類型字段複製到新物件中。然而,當數據是參考類型時,只有參考本身被複製,而不是被參考的物件本身。因此,原物件和複製物件將指向同一個物件。這意味著,如果修改了複製物件中的參考類型字段,原物件中的相同字段也會被修改。
在C#中,可以使用MemberwiseClone()
方法來實現淺層複製。這個方法會創建一個新的物件,並將原物件的所有字段複製到新物件中。但是,如果字段是參考類型,則只複製參考,而不是參考的物件本身。
public object Shallowcopy()
{
return this.MemberwiseClone();
}
深層複製(Deep Copy)
深層複製則是創建一個新的物件,並將原物件的所有字段(包括參考類型字段)複製到新物件中。這意味著,即使是參考類型字段,也會創建一個新的物件來替換原物件中的參考。因此,原物件和複製物件之間的參考類型字段是完全獨立的,修改其中一個不會影響另一個。
在C#中,實現深層複製需要手動實現。這通常涉及到創建一個新的物件,並將原物件的所有字段(包括參考類型字段)複製到新物件中,並確保參考類型字段也被複製。
深層複製的寫法有很多種,
方法1: 二進制序列化(Binary Serialization)
- 複製對象 Class 必需標記 [Serializable] 標籤
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public static T DeepClone<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", nameof(source));
}
if (source != null)
{
using (MemoryStream stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
return default(T);
}
static void Main(string[] args)
{
Person originalPerson = new Person { Name = "John Doe", Age = 30 };
Person clonedPerson = originalPerson.DeepClone();
Console.WriteLine($"Original Person: {originalPerson.Name}, {originalPerson.Age}");
Console.WriteLine($"Cloned Person: {clonedPerson.Name}, {clonedPerson.Age}");
// 修改複製物件的屬性
clonedPerson.Name = "Jane Doe";
clonedPerson.Age = 25;
Console.WriteLine($"Modified Cloned Person: {clonedPerson.Name}, {clonedPerson.Age}");
Console.WriteLine($"Original Person remains unchanged: {originalPerson.Name}, {originalPerson.Age}");
}
//執行結果:
//Original Person: John Doe, 30
//Cloned Person: John Doe, 30
//Modified Cloned Person: Jane Doe, 25
//Original Person remains unchanged: John Doe, 30
總結
- 淺層複製:創建一個新的物件,並將原物件的值類型字段複製到新物件中。參考類型字段的參考被複製,而不是被參考的物件本身。
- 深層複製:創建一個新的物件,並將原物件的所有字段(包括參考類型字段)複製到新物件中,確保參考類型字段也被複製。
這兩種複製方式在不同的情況下有不同的用途和效果,選擇使用哪種方式取決於具體的需求和應用場景。
留言
張貼留言