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;
            }
        }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code bean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值