• 改善C#程序的建议1:非用ICloneable不可的理由


    好吧,我承认,这是一个反标题,实际的情况是:我找不到一个非用ICloneable不可的理由。事实上,接口ICloneable还会带来误解,因为它只有一个Clone方法。

    我们都知道,对象的拷贝分为:浅拷贝和深拷贝。ICloneable仅有一个Clone方法使我们无法从命名的角度去区分到底是哪个拷贝。

    浅拷贝:将对象的字段复制到副本(新的对象)中,同时将字段的值也赋值过去,但是引用类型字段只复制引用,而不是引用类型本身。这意味着,源对象引用类型字段的值改变了,会影响到副本中对应的值也改变;

    深拷贝:将对象的字段复制到副本(新的对象)中,无论是值类型还是引用类型字段,都会复制类型本身及类型的值。这意味着,源对象引用类型字段的值改变了,不会影响到副本中对应的值;

    于是问题来了,如果类型继承了ICloneable接口,那么类型中的Clone是浅拷贝还是深拷贝。微软的解释是:你既可以在Clone方法中实现浅拷贝,也可以实现深拷贝。那么,为什么不直接提供两个方法呢?比如:DeepClone或者ShallowClone。还是,一般类型的创建,只要实现了浅拷贝就不需要再实现深拷贝(或者反之),所以我们没有必要提供两个方法。

    下面是一个既实现了浅拷贝也实现深拷贝的例子:

    代码
    [Serializable]
    class Employee : ICloneable
    {
    publicstring IDCode { get; set; }
    publicint Age { get; set; }
    public Department Department { get; set; }

    #region ICloneable 成员

    publicobject Clone()
    {
    returnthis.MemberwiseClone();
    }

    #endregion

    public Employee DeepClone()
    {
    using (Stream objectStream =new MemoryStream())
    {
    IFormatter formatter
    =new BinaryFormatter();
    formatter.Serialize(objectStream,
    this);
    objectStream.Seek(
    0, SeekOrigin.Begin);
    return formatter.Deserialize(objectStream) as Employee;
    }
    }

    public Employee ShallowClone()
    {
    return Clone() as Employee;
    }
    }

    实际上,ICloneable还带来一个问题(该问题Bill Wagner在Effcitive c#中曾经论述过),那就是:如果类型继承自ICloneable,但是同时它不是一个Sealed类型的话,它们的子类的默认Clone方法会带来BUG(子类的Clone方法会返回父类的副本,而不是子类本身)。这会逼迫所有的子类都重写Clone方法;

    ICloneable的Clone方法的另一个问题是:它不是类型安全的,它返回的是Object,使用它的时候还设计到转型的问题,而我们自己实现的Clone方法却可以规避掉这个问题(如上文代码)。

    综上所述,类型确实没必要继承ICloneable接口,如果类型本身需要实现拷贝功能,直接公开方法就行。如果在应用中你觉得确实必须实现这个接口的,来指正我吧。

    微信扫一扫,关注最课程(www.zuikc.com),获取更多我的文章,获取软件开发每日一练

  • 相关阅读:
    webpack 热加载特别慢
    服务中台 镜像校验 格式 socp1.io:3000/ypt/ypt:12aaa_1 正则 /^([az09\.\:]+)\.([az]+)\:([az09]+)\/([az09\.]+)\/([az09_.:]+)$/
    Vue报错:Vue ERROR TypeError: Cannot read property “upgrade” of undefined
    antd 使用form表单校验 默认值问题 以及 关闭弹窗组件后再次打开里面还有上次的值
    Unable to resolve module `@babel/runtime/helpers/objectSpread`
    网易公开课(数学微课帮)初中数学教学视频学习进度
    【noi2019集训题1】 脑部进食 期望dp+高斯消元
    【xsy1300】 原题的旅行 最短路+倍增
    【xsy2978】Product of Roots 生成函数+多项式ln+多项式exp
    【NOI2019集训题2】 序列 后缀树+splay+dfs序
  • 原文地址:https://www.cnblogs.com/luminji/p/1948826.html
Copyright © 2020-2023  润新知