您的位置:首页 > 编程语言 > C#

C#中深复制的实现

2018-03-08 15:51 316 查看

浅复制

object对象中以定义了MemberwiseClone()方法来实现浅复制,我们只需调用该方法即可(注意:该方法访问控制为protected)



class Program
{
public static void Main(string[] args)
{
var classA1 = new ClassA
{
a = 1,
b = "haha",
d = new ClassB{ c ="haha" }
};

var classA2 = (ClassA)classA1.Clone();

classA2.b = "xixi";
classA2.d.c = "xixi";
Console.WriteLine("classA1.b=" + classA1.b + "\nclassA2.b=" + classA2.b);
Console.WriteLine("classA1.d.c=" + classA1.d.c + "\nclassA2.d.c=" + classA2.d.c);
}

public class ClassA : ICloneable
{
public int a;

public string b;

public ClassB d;

public object Clone()
{
return MemberwiseClone();
}
}

public class ClassB
{
public string c;
}
}


输出结果:

classA1.b=haha

classA2.b=xixi

classA1.d.c=xixi

classA2.d.c=xixi


这里有个问题:string也是引用类型,更改使用浅复制的到classA2对象的b的值后,为什么classA1对象的b的值为什么没有跟着变化?

知识点:C#中字符串的值是不可修改的,执行修改字符串的操作时,会重新创建一个新的string对象,然后让变量指向新对象的地址。

深复制

通过序列化实现

//只需修改Clone方法的实现,同时使用[Serializable]标记ClassA类和ClassB类为可序列化,其他部分不变
[Serializable]
public class ClassA : ICloneable
{
public int a;

public string b;

public ClassB d;

public object Clone()
{
using (MemoryStream stream = new MemoryStream(1000))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(stream);
}
}
}

[Serializable]
public class ClassB
{
public string c;
}


通过Json实现

using Newtonsoft.Json;

public object Clone()
{
var str = JsonConvert.SerializeObject(this).ToString();
return JsonConvert.DeserializeObject<ClassA>(str);
}


相比于序列化,使用Json的方式不用给每个用到的类添加[Serializable]标记(修改原类),且更简洁
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  深复制