.NET的深复制方法(以C#语言为例)

2019-12-30 14:21:19于海丽

很多时候我们复制一个对象实例A到实例B,在用实例B去做其他事情的时候,会对实例B进行修改,为保证对B的修改不会影响到A的正常使用,就需要使用到深复制。

我在网上搜到一些深复制的方法,同时写了几组例子对这些方法进行测试。

我的操作系统版本为Win7旗舰版,.NET Framework版本是4.5

测试程序

我建了一个C#窗体应用程序(Winform),其主窗口FormMain的Load函数内容如下:


private void FormMain_Load(object sender, EventArgs e)
{
 //测试1:深度复制 自定义类
 try
 {
  Console.WriteLine("=== 深度复制 自定义类 ===");
  TestClass test1 = new TestClass();
  test1.a = 10;
  test1.b = "hello world!";
  test1.c = new string[] { "x", "y", "z" };
  TestClass test2 = new TestClass();
  test2.a = 11;
  test2.b = "hello world2!";
  test2.c = new string[] { "i", "j", "k" };
  test1.d = test2;
  Console.WriteLine("---test1_start---");
  Console.WriteLine(test1);
  Console.WriteLine("---test1_end---");
  TestClass test3 = (TestClass)DataManHelper.DeepCopyObject(test1);
  Console.WriteLine("---test3_start---");
  Console.WriteLine(test3);
  Console.WriteLine("---test3_end---");
 }
 catch (Exception ex)
 {
  Console.WriteLine(ex.ToString());
 }

    //测试2:深度复制 可序列化的自定义类
   


 try
 {
  Console.WriteLine("=== 深度复制 可序列化的自定义类 ===");
  TestClassWithS test1 = new TestClassWithS();
  test1.a = 10;
  test1.b = "hello world!";
  test1.c = new string[] { "x", "y", "z" };
  TestClassWithS test2 = new TestClassWithS();
  test2.a = 11;
  test2.b = "hello world2!";
  test2.c = new string[] { "i", "j", "k" };
  test1.d = test2;
  Console.WriteLine("---test1_start---");
  Console.WriteLine(test1);
  Console.WriteLine("---test1_end---");
  TestClassWithS test3 = (TestClassWithS)DataManHelper.DeepCopyObject(test1);
  Console.WriteLine("---test3_start---");
  Console.WriteLine(test3);
  Console.WriteLine("---test3_end---");
 }
 catch (Exception ex)
 {
  Console.WriteLine(ex.ToString());
 }

    //测试3:深度复制 DataTable
  


 try
 {
  Console.WriteLine("=== 深度复制 DataTable ===");
  DataTable dtKirov = new DataTable("TestTable");
  dtKirov.Columns.Add("Col1");
  dtKirov.Columns.Add("Col2");
  dtKirov.Columns.Add("Col3");
  dtKirov.Rows.Add("1-1", "1-2", "1-3");
  dtKirov.Rows.Add("2-1", "2-2", "2-3");
  dtKirov.Rows.Add("3-1", "3-2", "3-3");
  Console.WriteLine("=== 复制前 ===");
  for (int i = 0; i < dtKirov.Columns.Count; i++)
  {
   Console.Write(dtKirov.Columns[i].ColumnName + "t");
  }
  Console.WriteLine("n-----------------");
  for (int i = 0; i < dtKirov.Columns.Count; i++)
  {
   for (int j = 0; j < dtKirov.Rows.Count; j++)
   {
    Console.Write(dtKirov.Rows[i][j].ToString() + "t");
   }
   Console.WriteLine();
  }
  Console.WriteLine();
  DataTable dtDreadNought = (DataTable)DataManHelper.DeepCopyObject(dtKirov);
  Console.WriteLine("=== 复制后 ===");
  for (int i = 0; i < dtDreadNought.Columns.Count; i++)
  {
   Console.Write(dtDreadNought.Columns[i].ColumnName + "t");
  }
  Console.WriteLine("n-----------------");
  for (int i = 0; i < dtDreadNought.Columns.Count; i++)
  {
   for (int j = 0; j < dtDreadNought.Rows.Count; j++)
   {
    Console.Write(dtDreadNought.Rows[i][j].ToString() + "t");
   }
   Console.WriteLine();
  }
  Console.WriteLine();
 }
 catch (Exception ex)
 {
  Console.WriteLine(ex.ToString());
 }