首页 > 应用开发 > > C#中的深拷贝与浅拷贝
浅拷贝和深拷贝之间的区别:
浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值他将反映在原始对象中,也就是说原始对象中对应的字段也会发生变化。
深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一个新的和原始对象中对应字段相同(内容相同)的字段,也就是说这个引用和原始对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对象中对应字段的内容。
所以对于原型模式(prototype pattern)也有不同的两种处理方法:对象的浅拷贝和深拷贝
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
下面为一个常用的类。
[Serializable]
public class Persopn
{
public string Name { get; set; }
public int Age { get; set; }
public List
}
其中Likes是引用类型,需要序列化或发序列化时,需要加上[Serializable]特性。
下面说一下浅拷贝,直接上代码:
public object ShallowCopy()
{
return this.MemberwiseClone();
}
接下来说深拷贝,深拷贝有多种方式实现,下面分别一一说明:
通过反射实现
public static T DeepCopyByReflect
{
//如果是字符串或值类型则直接返回
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.Instance | BindingFlags.Static);
foreach (FieldInfo field in fields)
{
try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
catch { }
}
return (T)retval;
}
通过xml序列化实现
public static T DeepCopyByXml
{
object retval;
using (MemoryStream ms = new MemoryStream())
{
XmlSerializer xml = new XmlSerializer(typeof(T));
xml.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
retval = xml.Deserialize(ms);
ms.Close();
}
return (T)retval;
}
通过二进制序列化
public static T DeepCopyByBin
{
object retval;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
//序列化成流
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
//反序列化成对象
retval = bf.Deserialize(ms);
ms.Close();
}
return (T)retval;
}
通过Newtonsoft序列化
public static T CloneJson
{
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};
return JsonConvert.DeserializeObject
}
好了,目前c#常用的深拷贝基本就上面几个,个人推荐最后一种,反射速度最慢,不建议采用。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/623/viewspace-3147537/ ,如需转载,请注明出处,否则将追究法律责任。