抽象超类型Animal有许多子类型,Cat,Dog等。这些子类型只有一个构造函数和动物中的虚拟方法的覆盖 - 即它们没有自己独有的属性或方法。 Class Zoo有许多引用和动物列表,但不知道或者将不需要了解Cats,Dogs等。启用动态深度复制的最佳方法是什么? ,最好在Cat,Dog等中很少或没有新代码。
答案 0 :(得分:3)
如果您担心需要创建新的Clone
实现,只是为了获得正确的类型(因为基类中this
的类型是移动目标),您可以使用Activator.CreateInstance
为覆盖Animal
的所有类型创建当前类型的新实例:
var copy = (Animal)Activator.CreateInstance(this.GetType());
copy.HasClaws = this.HasClaws; // copy Animal properties
您需要一个无参数构造函数才能使此Activator.CreateInstance
调用工作。
答案 1 :(得分:1)
深度克隆对象的一种快捷方法是将其序列化为MemoryStream
,然后将其反序列化为对象图。反序列化的副本将是一个深度克隆的图形,不会引用原始对象。与手动克隆对象相比,它可能需要更多的内存和CPU密集,但编码工作要少得多;最终结果通常是可以接受的。
以下是从CodeProject获取的一项实施:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/// <span class="code-SummaryComment"><summary></span>
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// <span class="code-SummaryComment"></summary></span>
public static class ObjectCopier
{
/// <span class="code-SummaryComment"><summary></span>
/// Perform a deep Copy of the object.
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><typeparam name="T">The type of object being copied.</typeparam></span>
/// <span class="code-SummaryComment"><param name="source">The object instance to copy.</param></span>
/// <span class="code-SummaryComment"><returns>The copied object.</returns></span>
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
可以像这样调用:
ObjectCopier.Clone(objectBeingCloned);