浅拷贝与深拷贝之间的区别:
浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值他将反映在原始对象中,也就是说原始对象中对应的字段也会发生变化。
深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一个新的和原始对象中对应字段相同(内容相同)的字段,也就是说这个引用和原始对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对象中对应字段的内容。
MemberwiseClone()是object类中的一个方法,用来实现类的浅克隆,
MemberwiseClone()方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
.net提供了一个ICloneable接口,该接口下有一个Clone()方法,你可以实现它用来实现你自己的克隆方式,比如深克隆或是浅克隆,
下面是一个深拷贝与浅拷贝的例子,代码如下:
/// <summary>
/// 深拷贝接口
/// </summary>
interface IDeepCopy
{
object DeepCopy();
}
/// <summary>
/// 浅拷贝接口
/// </summary>
interface IShallowCopy
{
object ShallowCopy();
}
[Serializable]
public class InvoiceDetailResponse : IDeepCopy, IShallowCopy
{
public Guid merchant_id { get; set; }
public int age { get; set; }
/// <summary>
/// 浅拷贝
/// </summary>
/// <returns></returns>
public object ShallowCopy()
{
return this.MemberwiseClone();
}
/// <summary>
/// 深拷贝 序列化方式【不建议使用二进制流方法,推荐使用反射方式】
/// </summary>
/// <returns></returns>
public object DeepCopy()
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
return (InvoiceDetailResponse)bFormatter.Deserialize(stream);
}
}
/// <summary>
/// 深拷贝 反射方式
/// </summary>
/// <returns></returns>
public static T DeepCopyByReflection<T>(T obj)
{
if (obj is string || obj.GetType().IsValueType)
return obj;
object retval = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance);
foreach(var field in fields)
{
try
{
field.SetValue(retval, DeepCopyByReflection(field.GetValue(obj)));
}
catch
{
}
}
return (T)retval;
}
}