时间:2023/12/17来源:本站原创作者:佚名

在C#中,深拷贝和浅拷贝分别指的是对象的复制方式。

概念:

浅拷贝:浅拷贝只是拷贝了对象的引用,而不是对象本身。因此,修改拷贝后的对象会影响到原对象。

深拷贝:深拷贝拷贝了对象本身,而不是对象的引用。因此,修改拷贝后的对象不会影响到原对象。

例如,我们有一个类Person,它有两个属性:Name和Address。

classPerson{publicstringName{get;set;}publicAddressAddress{get;set;}}

classAddress{publicstringStreet{get;set;}publicstringCity{get;set;}}

如果我们使用浅拷贝,我们将创建一个新的Person对象,它的Name和Address属性都是与原始对象相同的引用。如果我们更改拷贝的对象的Address属性,则原始对象的Address属性也将更改。

如果我们使用深拷贝,我们将创建一个新的Person对象,它的Name和Address属性都是与原始对象不同的副本。如果我们更改拷贝的对象的Address属性,则原始对象的Address属性不会更改。

在C#中,可以使用MemberwiseClone()方法来实现浅拷贝。这个方法可以在基类Object中找到,可以在所有类型上调用。这个方法会返回一个新的对象,它的属性值与调用该方法的对象相同。

例如:

Personperson1=newPerson();person1.Name="John";person1.Address=newAddress{Street="MainSt",City="Seattle"};Personperson2=(Person)person1.MemberwiseClone();person2.Name="Jane";person2.Address.City="Boston";Console.WriteLine(person1.Name);//"John"Console.WriteLine(person1.Address.City);//"Boston"

我们可以看到,person1和person2的Name属性是不同的,但是他们的Address属性是相同的引用,因此修改person2.Address.City会影响到person1.Address.City。

而深拷贝可以通过序列化和反序列化来实现。或者使用深拷贝第三方库来实现。

例如:

Personperson1=newPerson();person1.Name="John";person1.Address=newAddress{Street="MainSt",City="Seattle"};Personperson2=(Person)person1.DeepClone();person2.Name="Jane";person2.Address.City="Boston";Console.WriteLine(person1.Name);//"John"Console.WriteLine(person1.Address.City);//"Seattle"

我们可以看到,person1和person2的Name属性是不同的,而且person2.Address.City="Boston"不会影响到person1.Address.City。

还有一种方法是使用IClonable接口来实现深拷贝,但是这种方法有时不够灵活。

还有一种方法是使用.NETFramework中提供的序列化和反序列化来实现深拷贝。这种方法适用于所有可序列化的对象。

例如,可以使用BinaryFormatter或者XmlSerializer序列化对象,然后使用反序列化来创建副本。

例如:

Personperson1=newPerson();person1.Name="John";person1.Address=newAddress{Street="MainSt",City="Seattle"};using(varms=newMemoryStream()){varformatter=newBinaryFormatter();formatter.Serialize(ms,person1);ms.Position=0;Personperson2=(Person)formatter.Deserialize(ms);person2.Name="Jane";person2.Address.City="Boston";}Console.WriteLine(person1.Name);//"John"Console.WriteLine(person1.Address.City);//"Seattle"

还可以使用JSON.Net序列化和反序列化来实现深拷贝。

例如:

Personperson1=newPerson();person1.Name="John";person1.Address=newAddress{Street="MainSt",City="Seattle"};stringjson=JsonConvert.SerializeObject(person1);Personperson2=JsonConvert.DeserializeObjectPerson(json);person2.Name="Jane";person2.Address.City="Boston";Console.WriteLine(person1.Name);//"John"Console.WriteLine(person1.Address.City);//"Seattle"

总之,对于深拷贝和浅拷贝,可以通过MemberwiseClone()方法实现浅拷贝,并通过序列化和反序列化实现深拷贝。还可以使用第三方库来实现。

对于深拷贝和浅拷贝,还有一些其它的实现方法。

一种方法是使用C#自带的深拷贝方法,使用C#9中的record。Record是C#9.0新增的一种类型,它可以自动生成深拷贝方法,并且可以自动生成基于值的比较器。

例如

recordPerson{publicstringName{get;init;}publicAddressAddress{get;init;}}recordAddress{publicstringStreet{get;init;}publicstringCity{get;init;}}Personperson1=newPerson("John",newAddress("MainSt","Seattle"));Personperson2=person1with{Name="Jane",Address=newAddress("MainSt","Boston")};Console.WriteLine(person1.Name);//"John"Console.WriteLine(person1.Address.City);//"Seattle"

另一种方法是使用ExpressionTree来实现深拷贝。ExpressionTree是C#中一种强大的技术,可以用于动态编译和执行代码。可以使用ExpressionTree来创建深拷贝的代码,这样可以更好地控制深拷贝的实现。

总之,对于深拷贝和浅拷贝,有多种不同的实现方法可以选择。可以根据项目需求来选择合适的实现方式。

另外,在C#中还有一些第三方库可以用来实现深拷贝,例如:

FastDeepCloner

DeepCloner

ObjectCloner

CloneExtensions

这些第三方库都提供了简单易用的API来实现深拷贝,它们都可以处理复杂的对象结构和循环引用的问题。

例如,使用FastDeepCloner库进行深拷贝,可以这样写:

Personperson1=newPerson();person1.Name="John";person1.Address=newAddress{Street="MainSt",City="Seattle"};Personperson2=FastDeepCloner.DeepCloner.Clone(person1);person2.Name="Jane";person2.Address.City="Boston";Console.WriteLine(person1.Name);//"John"Console.WriteLine(person1.Address.City);//"Seattle"

使用第三方库可以更简便地实现深拷贝,并且能够更好地处理复杂的对象结构和循环引用的问题。

内容有点多,希望以上能够帮助你更好地理解C#中的深拷贝和浅拷贝,选择合适的实现方法并应用于实际项目中。


转载请注明原文网址:http://www.helimiaopu.com/cksc/cksc/12856.html
------分隔线----------------------------