【Unity100个实用小技巧】C# 实现深拷贝的五种方式

  • ☀️博客主页:CSDN博客主页
  • 💨本文由 萌萌的小木屋 原创,首发于 CSDN💢
  • 🔥学习专栏推荐:面试汇总
  • ❗️游戏框架专栏推荐:游戏实用框架专栏
  • ⛅️点赞 👍 收藏 ⭐留言 📝,如有错误请指正
  • 📆 未来很长,值得我们全力奔赴更美好的生活✨

  • ------------------❤️分割线❤️-------------------------

请添加图片描述​​​请添加图片描述​​​请添加图片描述​​​

​​​


目的:方便需要的时候直接查找使用

需求:创建一个新的对象,该对象具有原始对象全部属性和方法,同时保证原始对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。

实现一:通过文件方式

  /// <summary>
    /// 深拷贝方法一:这种方式比较耗费性能,而且遇到对象中有值为null就会报错,不建议使用
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static T DeepCopy<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.Instance | BindingFlags.Static);
        foreach (FieldInfo field in fields)
        {
            try { field.SetValue(retval, DeepCopy(field.GetValue(obj))); }
            catch { }
        }
        return (T)retval;
    }

实现二:通过序列化拷贝

  /// <summary>
    /// 二进制序列化拷贝
    /// 这种方法相对性能会高一些,遇到对象值为null时不会报错,使用此方法时需要在拷贝的对象实体上标记可序列化的特性
    //[Serializable]
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static T DeepCopyByBinary<T>(T obj)
    {
        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;
    }

实现三:利用Xml

 /// <summary>
    /// 方法三:利用xml序列化和反序列化实现深拷贝  
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public T DeepCopy<T>(T obj)
    {
        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;
    }

实现四:通过DataContractSerializer序列化

 /// <summary>
    /// 方法四:
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static T DeepCopy<T>(T obj)
    {
        object retval;
        using (MemoryStream ms = new MemoryStream())
        {
            DataContractSerializer ser = new DataContractSerializer(typeof(T));
            ser.WriteObject(ms, obj);
            ms.Seek(0, SeekOrigin.Begin);
            retval = ser.ReadObject(ms);
            ms.Close();
        }
        return (T)retval;
    }

实现五:通过Json序列化

 /// <summary>
    /// 方法五:通过Json序列化的方式深拷贝
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static T DeepCopyJson<T>(T obj)
    {
        object rel;
        using (MemoryStream ms = new MemoryStream())
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ms.Seek(0, SeekOrigin.Begin);
            rel = bf.Deserialize(ms);
            ms.Close();
        }
        return (T)rel;
    }

GitCode地址

有用点个Fork啊

更新记录

2023-5-30 更新了基础常用的Api

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C#实现单例模式有多种方式,其中一种常见的方式是使用静态变量。下面是一个在 Unity 中使用 C# 实现单例的示例代码: ```csharp public class MySingleton : MonoBehaviour { private static MySingleton instance; public static MySingleton Instance { get { if (instance == null) { instance = FindObjectOfType<MySingleton>(); if (instance == null) { GameObject go = new GameObject(); go.name = "MySingleton"; instance = go.AddComponent<MySingleton>(); DontDestroyOnLoad(go); } } return instance; } } private void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } } ``` 这个示例中,我们在类中定义了一个静态变量 instance,用于存储单例对象。在 Instance 属性中,我们首先检查 instance 是否为 null,如果是,就通过 FindObjectOfType 方法查找场景中是否已经存在 MySingleton 实例,如果存在就直接赋值 instance,否则就创建一个新的 GameObject,并添加一个 MySingleton 组件,再将其赋值给 instance。最后,我们返回 instance。 在 Awake 方法中,我们再次检查 instance 是否为 null,如果是,就将当前实例赋值给 instance,并调用 DontDestroyOnLoad 方法,以便在场景切换时不被销毁。如果 instance 不为 null,说明已经存在 MySingleton 实例了,我们就销毁当前实例。 使用时,我们可以通过 MySingleton.Instance 来获取单例对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我是小狼君

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

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

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

打赏作者

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

抵扣说明:

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

余额充值