字典类Dictionary复制

本文介绍了一种使用序列化和反序列化技术实现Dictionary类深度拷贝的方法,并详细解释了实现过程中需要注意的问题,包括如何正确地定义反序列化构造函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   1、实现拷贝一份Dictionary数据的类

    遍历原始Dictionay结构和数据进行赋值工作,性能很差,通过序列化和反序列化的方式来完成数据对象的深度拷贝工作,这种方式快速高效

    [Serializable]
    public class DictionaryCloneable<TKey, TValue> : Dictionary<TKey, TValue>,IDictionary<TKey, TValue>, ICloneable
    {
        public object Clone()
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Formatter =
                new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(null, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Clone));
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            Formatter.Serialize(stream, this);
            stream.Position = 0;
            object clonedObj = Formatter.Deserialize(stream);
            stream.Close();
            return clonedObj;
        }
    }

 

实现深度拷贝工作,只需这个类继承ICloneable接口,通过BinaryFormatter序列化器,首先先将对象实例序列化写入内存流中,然后反序列化流,返回反序列化对象即可。

 

2、特别注意:必须添加一个用于反序列化的构造函数,否则会报“未找到反序列化的类型对象的构造函数。”
对于这个错误、我们第一个反应是在反序列化的时候找不到默认(无参)的构造函数。但是再看DictionaryCloneable的定义,我们不曾定义任何构造函数,意味着它具有一个默认(无参)构造函数。实际上,这里并不是找不到默认(无参)构造函数,而是找不到一个具有特殊参数列表的构造函数。该构造函数接收两个参数,类型分别是:SerializationInfo和StreamingContext。所以我们的解决方案很简单,就是加上这么一个构造函数。为此我们从新定义DictionaryCloneable。

 

 [Serializable]
    public class DictionaryCloneable<TKey, TValue> : Dictionary<TKey, TValue>,IDictionary<TKey, TValue>, ICloneable
    {
        public DictionaryCloneable()
        {

        }

        //必须加上此构造函数,在反序列化时被调用,否则会报“未找到反序列化的类型对象的构造函数。”
        public DictionaryCloneable(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {

        }

        public object Clone()
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Formatter =
                new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(null, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Clone));
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            Formatter.Serialize(stream, this);
            stream.Position = 0;
            object clonedObj = Formatter.Deserialize(stream);
            stream.Close();
            return clonedObj;
        }
    }

如果一个类型实现了ISerializable接口(Dictionary<TKey, TValue>就实现了这个接口),你就应该定义如上一个构造函数。这算是一个约定,但是当你继承某个类型的时候,你往往会忘记这个约定。

 

3、使用

  public volatile Dictionary<int, CommControls.EnumCameraStyle> DicCameraStyleTemp = new Dictionary<int, CommControls.EnumCameraStyle>();
  objec t obj = DicCameraStyle.Clone();  
  DicCameraStyleTemp = obj as Dictionary<int, CommControls.EnumCameraStyle>;
  DicCameraStyle.Clear();

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值