首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不将类标记为可序列化的情况下深入复制类

如何在不将类标记为可序列化的情况下深入复制类
EN

Stack Overflow用户
提问于 2010-03-30 12:22:48
回答 7查看 25.7K关注 0票数 19

鉴于以下课程:

代码语言:javascript
运行
复制
class A
{
    public List<B> ListB;

    // etc...
}

其中B是另一个可以继承/包含其他类的类。

鉴于这种情况:

  1. A是一个大型类,包含许多引用类型。
  2. 我不能将B标记为[Serializable],因为我无法访问B的源代码

执行深度复制的下列方法不起作用:

  1. 我不能使用ICloneableMemberwiseClone作为类A包含许多引用类型
  2. 我不能为A编写一个复制构造函数,因为这个类很大并且不断地被添加到其中,并且包含不能被深度复制的类(比如B)。
  3. 我不能使用序列化,因为我不能将包含的类(如B,其中没有可用的源代码)标记为[Serializable]

如何深入复制类A

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-03-30 12:46:50

无论如何,我停止了使用序列化进行深度复制,因为没有足够的控制(不是每个类都需要以相同的方式复制)。然后,我开始实现自己的深拷贝接口,并以复制的方式复制每个属性。

复制引用类型的典型方法:

  • 使用复制构造函数
  • 使用工厂方法(如:不可变类型)
  • 使用你自己的“克隆人”
  • 只复制参考资料(如。其他根类型)
  • 创建新实例并复制属性(例如。没有副本构造函数的类型)

示例:

代码语言:javascript
运行
复制
class A
{
  // copy constructor
  public A(A copy) {}
}

// a referenced class implementing 
class B : IDeepCopy
{
  object Copy() { return new B(); }
}

class C : IDeepCopy
{
  A A;
  B B;
  object Copy()
  {
    C copy = new C();

    // copy property by property in a appropriate way
    copy.A = new A(this.A);
    copy.B = this.B.Copy();
  }
}

你可能会认为这是一项巨大的工作。但是在最后,它是简单和直接的,可以调整到需要的地方,做你需要做的事情。

票数 10
EN

Stack Overflow用户

发布于 2012-04-01 03:44:11

你可以试试这个。对我来说很管用

代码语言:javascript
运行
复制
    public static object DeepCopy(object obj)
    {
        if (obj == null)
            return null;
        Type type = obj.GetType();

        if (type.IsValueType || type == typeof(string))
        {
            return obj;
        }
        else if (type.IsArray)
        {
            Type elementType = Type.GetType(
                 type.FullName.Replace("[]", string.Empty));
            var array = obj as Array;
            Array copied = Array.CreateInstance(elementType, array.Length);
            for (int i = 0; i < array.Length; i++)
            {
                copied.SetValue(DeepCopy(array.GetValue(i)), i);
            }
            return Convert.ChangeType(copied, obj.GetType());
        }
        else if (type.IsClass)
        {

            object toret = Activator.CreateInstance(obj.GetType());
            FieldInfo[] fields = type.GetFields(BindingFlags.Public |
                        BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (FieldInfo field in fields)
            {
                object fieldValue = field.GetValue(obj);
                if (fieldValue == null)
                    continue;
                field.SetValue(toret, DeepCopy(fieldValue));
            }
            return toret;
        }
        else
            throw new ArgumentException("Unknown type");
    }

感谢代码项目上的DetoX83 文章

票数 3
EN

Stack Overflow用户

发布于 2010-03-30 12:31:13

你不能这么做吗?

代码语言:javascript
运行
复制
[Serializable]
class A
{
     ...
    [NonSerialized]
    public List<B> ListB;
    ....
}

,然后参考如何在.NET (特别是C#)中对对象进行深度复制?获取克隆函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2545025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档