C#对象的深层副本

use*_*192 7 c# deep-copy

我正在研究一些用C#编写的代码.在这个应用程序中,我有一个自定义集合定义如下:

public class ResultList<T> : IEnumerable<T>
{
  public List<T> Results { get; set; }
  public decimal CenterLatitude { get; set; }
  public decimal CenterLongitude { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Results使用的类型是三种自定义类型之一.每个自定义类型的属性只是基本类型(整数,字符串,bools,int?,bool?).以下是其中一种自定义类型的示例:

public class ResultItem
{
  public int ID { get; set; }
  public string Name { get; set; }
  public bool? isLegit { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如何执行我创建的ResultList对象的深层副本.我发现这篇文章:创建集合中所有元素的深层副本的通用方法.但是,我无法弄清楚如何做到这一点.

Dou*_*las 15

涉及编码最少的方法是通过序列化和反序列化BinaryFormatter.

您可以定义以下扩展方法(取自Kilhoffer的答案):

public static T DeepClone<T>(T obj)
{
    using (var ms = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(ms, obj);
        ms.Position = 0;
        return (T)formatter.Deserialize(ms);
    }
}
Run Code Online (Sandbox Code Playgroud)

......然后打电话:

ResultList<T> clone = DeepClone(original);
Run Code Online (Sandbox Code Playgroud)


Rei*_*las 9

其中一个为什么你ResultList类不会乔恩斯基特的工作原因,例如是因为它没有实现ICloneable接口.

在您需要克隆的所有类上实现ICloneable,例如

public class ResultItem : ICloneable
{
  public object Clone()
  {
    var item = new ResultItem
                 {
                   ID = ID,
                   Name = Name,
                   isLegit = isLegit
                 };
    return item;
  }
}
Run Code Online (Sandbox Code Playgroud)

还有ResultList:

public class ResultList<T> : IEnumerable<T>, ICloneable where T : ICloneable
{
  public List<T> Results { get; set; }
  public decimal CenterLatitude { get; set; }
  public decimal CenterLongitude { get; set; }

  public object Clone()
  {
    var list = new ResultList<T>
                 {
                   CenterLatitude = CenterLatitude,
                   CenterLongitude = CenterLongitude,
                   Results = Results.Select(x => x.Clone()).Cast<T>().ToList()
                 };
    return list;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后制作对象的深层副本:

resultList.clone();
Run Code Online (Sandbox Code Playgroud)