zoukankan      html  css  js  c++  java
  • C#深拷贝

    C#的深拷贝,须要自己实现逻辑,眼下我没有发现微软提供了可供调用的API。

    微软仅仅是提供ICloneable接口,此接口仅仅是为我们提供了一个规范,必须实现object Clone();方法,例如以下代码:

    public class Person : ICloneable
    {
        public int ID { get; set; }
        public string Name { get; set; }
        Object Clone(){
            Person newPerson = new Person();
            newPerson.ID = this.ID;
            newPerson.Name = this.Name;
            return newPerson;
        }
    }

    以下是调用方法:

    Person oldPerson = new Person();
    oldPerson.ID = 1;
    oldPerson.Name = "Terry";
    Person newPerson = (Person)oldPerson.Clone();
    newPerson.Name = "Harry";
    Console.WriteLine("old person's name is " + oldPerson.Name);//他们输出的Name是不一致的,所以说实现了深拷贝
    Console.WriteLine("new person's name is " + newPerson.Name);

    此时可能会有人问了。既然详细实现逻辑还要自己写,干嘛要继承ICloneable接口呢?
    事实上微软定义了这么个接口,是基于软件project方面的考虑,提高代码的规范性。试想假设一个项目组有多个人在实现深拷贝。而又没有继承ICloneable这个接口,那么结果会是什么样呢?能够肯定的是,在接口、拷贝方法命名上会有多个版本号存在。

    当然。假设我们不想这么麻烦,能够考虑使用反射的机制来实现深拷贝,只是这种话对性能会有影响,以下是例子代码:

    public static class ExntedHelper
        {
            /// <summary>
            /// 深复制
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="source"></param>
            /// <returns></returns>
            public static T CopySameFieldObject<T>(this Object source)
            {
                Type _SrcT = source.GetType();
                Type _DestT = typeof(T);
    
                // 构造一个要转换对象实例
                Object _Instance = _DestT.InvokeMember("", BindingFlags.CreateInstance, null, null, null);
    
                // 这里指定搜索全部公开和非公开的字段
                FieldInfo[] _SrcFields = _SrcT.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    
                // 将源头对象的每一个字段的值分别赋值到转换对象里,由于假定字段都一样。这里就不做容错处理了
                foreach (FieldInfo field in _SrcFields)
                {
                    if (field.GetValue(source) != null)
                            _DestT.GetField(field.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).
                                SetValue(_Instance, field.GetValue(source));
                }
    
                return (T)_Instance;
            }
        }

    调用代码:

    Person oldPerson = new Person();
    oldPerson.ID = 1;
    oldPerson.Name = "Terry";
    Person newPerson = oldPerson.CopySameFieldObject<Person>();
    newPerson.Name = "Harry";
    Console.WriteLine("old person's name is " + oldPerson.Name);//他们输出的Name是不一致的,所以说实现了深拷贝
    Console.WriteLine("new person's name is " + newPerson.Name);
  • 相关阅读:
    CGI编程完全手册(转)
    Linux下读写芯片的I2C寄存器(转)
    Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析
    H264中的SPS、PPS提取与作用(转)
    H264码流打包分析(精华)--转
    嵌入式Linux USB WIFI驱动的移植(转)
    推荐一款技术人必备的接口测试神器:Apifox
    Java 设置、删除、获取Word文档背景(基于Spire.Cloud.SDK for Java)
    Java 添加、删除、格式化Word中的图片( 基于Spire.Cloud.SDK for Java )
    Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java)
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7372732.html
Copyright © 2011-2022 走看看