1

早上好,下午或晚上,

当将给定的类实现为不可变的类时,没有任何方法或属性以任何方式公开私有/内部字段,浅拷贝是一种不好的做法,还是可以毫无问题地完成,因为它可能需要实例化的对象少得多?

非常感谢。

4

4 回答 4

7

一般来说(可能有一些例外),如果你的类型是完全不可变的,那么根本不需要复制它,无论是浅的还是深的。您可以只传递原始实例。

正确不可变类型的一大优点是我可以将同一个实例传递给所有消费者,安全地知道他们都不能改变它并为另一个消费者破坏它。

于 2011-03-22T17:40:24.593 回答
4

使用不可变数据结构的优点之一是,当您需要更改某些内容时,只执行浅拷贝可以提高效率。显然,如果您不更改任何内容,则根本不需要制作任何副本。

例如,您可以有一个像这样的不可变类:

class Data
{
    ...

    Datum x;
    public Datum X { get { return x; } }
    public Data WithX(Datum x)
    {
        var newData = (Data)this.MemberwiseClone(); // <-- Shallow copy!
        newData.x = x;
        return newData;
    }
}
于 2011-03-22T17:41:26.340 回答
2

这取决于您想要支持的不变性的语义 - 如果您使用浅拷贝,则必须保证您共享的对象也不会发生变化,否则这将被视为观察者的变化。除此之外,共享对象实际上在性能方面非常有益,即您只需要这些对象一次而不是 N 次(另请参阅Flyweight 模式)。

于 2011-03-22T17:41:12.673 回答
0

假设您的意思是复制的对象(图中的“第一级”)是不可变的,那么进行浅拷贝是一种很好的做法。

此外,不可变对象可以具有返回自身的克隆方法,因此如果包含它们的对象被“深度复制”,那么它实际上就是一个浅拷贝。例如,System.String 实现了 ICloneable:

public object Clone()
{
  return this;
}

就个人而言,我推荐以下变体,以减少不通过接口调用时的转换需求:

public class MyImmutableClass : ICloneable
{
  public MyImmutableClass Clone()
  {
    return this;
  }
  ICloneable.Clone()
  {
    return this;
  }
}
于 2011-03-22T17:47:09.973 回答