当前位置:   article > 正文

如果通过 C# 实现对象的深复制 ?

c#对于对象里面嵌套对象的深复制实现

咨询区

  • NakedBrunch

我想实现 引用类型对象 之间的深复制,也就是在新的对象上修改不会影响到老的对象,我用了 C# 提供的 Clone 方法。

  1. MyObject myObj = GetMyObj(); // Create and fill a new object
  2. MyObject newObj = myObj.Clone();

但貌似这样行不通,请问该如何正确实现?

回答区

  • craastad

如果你的引用类型对象是 json 友好的,那你完全可以借助第三方工具将其转为 Json,比如 Json.NET ,参考如下的 Clone 扩展方法。

  1. public static T Clone<T>(this T theObject)
  2. {
  3.     string jsonData = JsonConvert.SerializeObject(theObject);
  4.     return JsonConvert.DeserializeObject<T>(jsonData);
  5. }

然后像下面这样使用。

NewObject = OldObject.Clone();
  • Stacked

如果你要快速实现,建议使用对象映射化工具 AutoMapper, 它是一个高效并且轻量级的将一个对象转为另一个对象,它的底层使用的是 Lambda 表达式树,参考如下代码:

  1. MyType source = new MyType();
  2. Mapper.CreateMap<MyType, MyType>();
  3. MyType target = Mapper.Map<MyType, MyType>(source);

上面的target就是深copy后的对象,如果你觉得这样还繁琐的化,再封装到一个扩展方法中去。

  1. public static T Copy<T>(this T source)
  2. {
  3.     T copy = default(T);
  4.     Mapper.CreateMap<T, T>();
  5.     copy = Mapper.Map<T, T>(source);
  6.     return copy;
  7. }

然后像下面这样使用。

MyType copy = source.Copy();
  • Marcell Toth

通常来说,做深层的copy,方法有如下几种。

  1. 序列化

本质上来说,序列化是非常慢的一种方式,而且还限制重重,比如说:

  1. BinaryFormatter 需要引用类型必须实现 Serializable 特性。

  2. JsonConverter 需要引用类型必须有无参构造函数。

  1. 表达式树

要先加速,可以使用 Expression Tree 或者 Reflection.Emit 来动态生成深复制代码,但这种原始的方式实现起来特别麻烦,我为此专门写了一个映射工具,参见 github:https://github.com/marcelltoth/ObjectCloner

实现起来非常方便,参考如下代码:

var clone = ObjectCloner.DeepClone(original);

我的方法 ~3x 于 Reflection, ~12x 于 Newtonsoft.Json 。

点评区

其实 Dapper 用的就是 Emit 来实现高速映射, AutoMapper 用的是 Expresstion Tree 实现高速映射,大家有兴趣可以了解下。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/86020
推荐阅读
相关标签
  

闽ICP备14008679号