C# 实现数组深拷贝的一种标准方法
首先让你的数据类实现接口 ICloneable
比如:
public class Info : INotifyPropertyChanged, ICloneable
{
// 实现ICloneable的Clone函数
public object Clone()
{
return this; //注意这里返回this
}
public Info(string time, string name, double score, string result)
{
this.Time = time;
this.Name = name;
this.Score = score;
this.Result = result;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
private string time;
public string Time
{
get { return time; }
set
{
time = value;
OnPropertyChanged(new PropertyChangedEventArgs("Time"));
}
}
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
private double score;
public double Score
{
get { return score; }
set
{
score = value;
OnPropertyChanged(new PropertyChangedEventArgs("Score"));
}
}
private string result;
public string Result
{
get { return result; }
set
{
result = value;
OnPropertyChanged(new PropertyChangedEventArgs("Result"));
}
}
}
那我们的数组就是该数据类的数组,为了让这个深拷贝方法通用,我们使用泛型.
这里我们使用的集合类型是ObservableCollection,你也可以改为List,或者其他类型。
public static ObservableCollection<T> DeepCopy<T>(IEnumerable<T> list)
where T : ICloneable
{
return new ObservableCollection<T>(list.Select(x => x.Clone()).Cast<T>());
}
Select 表示将表中的元素映射到另一张表。Cast表示转换集合中的每个元素的类型。
具体的使用方法如下:
//保留一个备份
infos_copy = DeepCopy<Info>(infos); //其中infos的类型:ObservableCollection<Info>
这样就实现了一个集合的拷贝。
----------------------------------------------------------------------------
还有一个更通用的方法,可以设拷贝任何可序列化的对象
首先我们需要定义个拓展方法,请回顾一下拓展方法的语法。
/// <summary>
/// 对象的深拷贝对象。
/// 注意“T”及其里面的引用类型必须标记为可序列化。
/// </summary>
public static T Copy<T>(this T obj)
where T : class
{
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
T CloneObject = default(T);
try
{
// 反序列化至另一个对象(即创建了一个原对象的深表副本)
CloneObject = (T)bf.Deserialize(ms);
}
catch (Exception ex)
{
LogHelper.Error("深拷贝对象失败", ex);
}
return CloneObject;
}
}
首先这里用到了this去去修饰一个泛型,而且这个泛型被约束为一个class类型。
也就是说,这个Copy函数几乎是为所以类写的扩展函数. 当然前提是这个类是可序列化的。
如果你需要深拷贝自定义的类,你需要为你的类添加一个[Serializable]标记:
[Serializable]
public class InfoAxisParameter
{
.....
}
那么使用的时候就十分的方便了:
InfoAxisParameter info = new InfoAxisParameter()
var info_copy = info.Copy()
这里有个小技巧,就是写一个扩展的类TypeExtension,然后将namespace设置为System
这样只要在工程里添加了这个TypeExtension类,那么其他地方无需添加其他的using就能使用这个扩展方法了
namespace System
{
public static partial class TypeExtension
{
/// <summary>
/// 对象的深拷贝对象。
/// 注意“T”及其里面的引用类型必须标记为可序列化。
/// </summary>
public static T Copy<T>(this T obj)
where T : class
{
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
T CloneObject = default(T);
try
{
// 反序列化至另一个对象(即创建了一个原对象的深表副本)
CloneObject = (T)bf.Deserialize(ms);
}
catch (Exception ex)
{
LogHelper.Error("深拷贝对象失败", ex);
}
return CloneObject;
}
}
}
作者:宋桓公
出处:http://www.cnblogs.com/douzi2/
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。