永发信息网

有没有更好的方式来创建在C#中深深浅浅的克隆

答案:1  悬赏:10  手机版
解决时间 2021-03-25 07:30
有没有更好的方式来创建在C#中深深浅浅的克隆
最佳答案
一、浅克隆:
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制,如图:

在C#中,通过实现ICloneable接口的Clone方法()调用MemberwiseClone方法)来实现浅克隆:
[csharp] view plain copy
public class WeeklyLog:ICloneable
{
public string Name { get; set; }
public Student Student { get; set; }

public object Clone()
{
return this.MemberwiseClone();
}
}
[csharp] view plain copy
{
public string Address { get; set; }
}
[csharp] view plain copy
static void Main(string[] args)
{
WeeklyLog log1 = new ProtoTypeTest.WeeklyLog();
log1.Name = "log1";
log1.Student = new ProtoTypeTest.Student() { Address = "haidian" };

WeeklyLog log2 = (WeeklyLog)log1.Clone();//调用浅克隆方法
Console.WriteLine(log1.Name);//log1
Console.WriteLine(log2.Name);//log1
Console.WriteLine(log1.Student.Address);//haidian
Console.WriteLine(log2.Student.Address);//haidian
Console.WriteLine(object.ReferenceEquals(log1, log2));//false
log2.Name = "log2";//修改克隆的对象的name属性
Console.WriteLine(log1.Name);//log1
Console.WriteLine(log2.Name);//log2
log2.Student.Address = "chaoyang";//修改克隆的对象的引用类型Student的Address属性
Console.WriteLine(log1.Student.Address);//chaoyang
Console.WriteLine(log2.Student.Address);//chaoyang
Console.ReadLine();

}
二、深克隆:
在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制,如图:

在C#语言中,如果需要实现深克隆,可以通过序列化(Serialization)等方式来实现。序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。下面我们使用深克隆技术来实现工作周报和附件对象的复制,由于要将附件对象和工作周报对象都写入流中,因此两个类用Serializable标识可序列化:
[Serializable]
public class WeeklyLog
{
public string Name { get; set; }
public Student Student { get; set; }

public WeeklyLog DeepClone()
{
object obj = null;
//将对象序列化成内存中的二进制流
BinaryFormatter inputFormatter = new BinaryFormatter();
MemoryStream inputStream;
using (inputStream = new MemoryStream())
{
inputFormatter.Serialize(inputStream, this);
}
//将二进制流反序列化为对象
using (MemoryStream outputStream = new MemoryStream(inputStream.ToArray()))
{
BinaryFormatter outputFormatter = new BinaryFormatter();
obj = outputFormatter.Deserialize(outputStream);
}
return (WeeklyLog)obj;
}

}

[Serializable]
public class Student
{
public string Address { get; set; }

}
static void Main(string[] args)
{
WeeklyLog log1 = new ProtoTypeTest.WeeklyLog();
log1.Name = "log1";
log1.Student = new ProtoTypeTest.Student() { Address = "haidian" };

WeeklyLog log2 = (WeeklyLog)log1.DeepClone();//调用深克隆方法
Console.WriteLine(log1.Name);//log1
Console.WriteLine(log2.Name);//log1
Console.WriteLine(log1.Student.Address);//haidian
Console.WriteLine(log2.Student.Address);//haidian
Console.WriteLine(object.ReferenceEquals(log1, log2));//false
log2.Name = "log2";//修改克隆的对象的name属性
Console.WriteLine(log1.Name);//log1
Console.WriteLine(log2.Name);//log2
log2.Student.Address = "chaoyang";//修改克隆的对象的引用类型Student的Address属性
Console.WriteLine(log1.Student.Address);//haidian
Console.WriteLine(log2.Student.Address);//chaoyang
Console.ReadLine();

}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
我们家要搬新家,但我一点都高兴不起来,甚至
访戴山道士怎么写
圣菩媞环境怎么样
后来明白了没有事情是完美的,也没有人生真正
选择哪个就业方向好
很多都是两攻一受文,但是有没有两受一攻文呀
上面现实的,真实姓名,对方隐藏,是不是对方
供奉道家三清有何感应?
上环疼吗?对身体有什么影响吗?后期危害大吗
拱架为什么要设置预拱度?怎样确定预拱度的大
16道看图猜成语的题,看你能答对多少?12345678
咏雪中的公大笑乐,公为什么笑
运行在太空中的“神舟”七号飞船直接构成
广式煲汤
文登市属于哪个省?
推荐资讯
了一天针好了,还需要打针吗
华为5000毫安或以上电池的手机有哪些
嬴政开启了秦国兼并六国模式,为何其他六国毫
各位大佬,我最后只想问做文案有前途吗
非移民国家是什么意思
东安区牡丹江吉利宠物用品地址在什么地方,想
乱世丽人行中历文轩最后和韩疏影在一起了吗
武刚至南宁跟车号在武刚是几点发车
苹果ipadian怎么安装微信
玄关墙面挂什么好风水
求魔兽世界LM人类战士20级职业任务流程!
为什么科二总是挂科?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?