【分享】.NET 对象深层克隆开源框架
2010-08-21 20:14 bugfly 阅读(2309) 评论(5) 编辑 收藏 举报对象深层克隆,要改变类原来的结构去协调功能,一般的做法是继承一个实现了克隆功能的基类或者实现克隆接口,我觉得颇为无谓,那种序列化的方式就更加另人难以接受,而这个框架直接引入后就可以使用克隆功能,它使用的是扩展方法,对泛型对象扩展克隆功能,所以直接可以调用克隆方法,测试过,深层克隆对象OK没问题。不足之处是Linq to Sql 里面复制有问题,搞了一天没找出原因。
以下是大致简介,英文内容很简单,我就不翻译了。(*^__^*) 嘻嘻……
Copyable: A framework for copying or cloning .NET objects
Copyable is a small framework for copying (or cloning, if you will) virtually any .NET object. It copies many objects automatically, and contains additional functionality for cases where it cannot automatically perform the copying. A detailed explanation and walkthrough is given in my post on Copyable.
Copyable is released under the MIT license. Download Copyable from here (binary) or here (source). The latest version is 1.0.0.0.
The Copyable framework
Copyable is a small framework for copying (or cloning, if you will) objects. The straightforward way of using it is to just reference the assembly it’s in from your project, and start copying!
1 SomeType instance = new SomeType(); 2 // ...do lots of stuff to the object... 3 SomeType copy = instance.Copy(); // Create a deep copy
The instance copy
is now a deep copy of instance
, no matter how complex the object graph for instance
is. The relations in the copy
graph is the same as in instance
, but all objects in the copy
object graph are copies of those in instance
.
For the automated copy to work, though, one of the following statements must hold for instance
:
- Its type must have a parameterless constructor, or
- It must be a
Copyable
, or - It must have an
IInstanceProvider
registered for its type.
Besides the Copy
method, The Copyable
class and IInstanceProvider
interface are the two major building blocks of the Copyable framework. Each of these blocks enable copying of objects that cannot automatically be copied.
The Copyable base class
Copyable
is an abstract base class for objects that can be copied. To create a copyable class, you simply subclass Copyable
and call its constructor with the arguments of your constructor.
1 class MyClass : Copyable 2 { 3 public MyClass(int a, double b, string c) 4 : base(a, b, c) 5 { 6 } 7 }
This code above makes MyClass
a copyable class. Note that if MyClass
had had a parameterless constructor, subclassing Copyable
would not be necessary.
MyClass
can now be copied just like the previous example.
1 MyClass a = new MyClass(1, 2.0, "3"); 2 MyClass b = a.Copy();
Copyable
base class solves many problems, but not all. Let’s say you wanted to copy a System.Drawing.SolidBrush
. This class does not have a parameterless constructor, which means it cannot be copied “automatically” by the framework. Also, you cannot alter it so that it subclasses Copyable
. So, what do you do? You create an instance provider.The IInstanceProvider interface
An instance provider is defined by the interface IInstanceProvider
. As the name clearly states, the implementation is a provider of instances. One instance provider can provide instances of one given type. The Copyable framework automatically detects IInstanceProvider
implementations in all assembies in its application domain, so all you need to do to create a working instance provider is to define it. No registration or other additional operations are required. To simplify the implementation of instance providers and the IInstanceProvider
interface, an abstract class InstanceProvider
is included in the framework.
1 public class SolidBrushProvider</dt> 2 <dd>InstanceProvider<SolidBrush> 3 { 4 public override SolidBrush CreateTypedCopy(SolidBrush s) 5 { 6 return new SolidBrush(s.Color); 7 } 8 }
This implementation will be used automatically by the Copyable framework. NOTE: To be usable, the instance provider MUST have a parameterless constructor.
The instance provider pattern does not solve the case where you want different initial states for your SolidBrush instances depending on which context you use them for copying. For those cases, an overload of Copy()
exists which takes an already created instance as an argument. This argument will become the copy.
1 SolidBrush instance = new SolidBrush(Color.Red); 2 instance.Color = Color.Black; 3 SolidBrush copy = new SolidBrush(Color.Red); 4 instance.Copy(copy); // Create a deep copy
copy
is now of the color Color.Black
.Limitations and pitfalls
Although this solution works in most cases, it’s not a silver bullet. Be aware when you copy classes that hold unmanaged resources such as handles. If these classes are designed on the premise that their resources are exclusive to them, they will manage them as they see fit. Imagine if you copied a class which holds a handle, disposed one of the instances, and continued using the copy. The handle will (probably) be freed by the original instance, and the copy will generate an access violation by attempting reading or writing freed memory.
That’s it! The Copyable framework can be downloaded from here. For those interested in reading more on extension methods, For additional information, MSDN provides an excellent explanation in the C# Programming Guide, and Scott Guthrie has an introduction article here.
Enjoy Copyable, and please let me know if you find it useful or come across any problems with it.
UPDATE 2009-12-11: Due to popular demand, I have made the source code for Copyable available under the MIT license. The source can be downloaded here.
UPDATE 2010-01-31: The requirement of parameterless constructors has been removed in the latest version of Copyable available on GitHub. A new release will follow soon.
作者:桀骜的灵魂
出处:http://www.cnblogs.com/HuntSoul/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。