Мелкие и Глубокие Копии в Неизменных Объектах - PullRequest
1 голос
/ 22 марта 2011

Доброе утро, день или ночь,

. При реализации данного класса как неизменяемого без каких-либо методов или свойств, предоставляющих какие-либо частные / внутренние поля, поверхностное копирование является плохой практикой или это может бытьсделано без проблем, так как может потребоваться создать гораздо меньше объектов?

Большое спасибо.

Ответы [ 4 ]

7 голосов
/ 22 марта 2011

Вообще говоря (и могут быть некоторые исключения из этого), если ваш тип является полностью неизменяемым, редко требуется копировать его вообще, мелкий или глубокий. Вы можете просто передать оригинальный экземпляр.

Одним из больших преимуществ правильно неизменяемых типов является то, что я могу передать один и тот же экземпляр всем потребителям, будучи уверенным, что ни один из них не может изменить его и испортить для другого потребителя.

4 голосов
/ 22 марта 2011

Одним из преимуществ использования неизменяемых структур данных является то, что вы можете быть намного более эффективными, делая только полные копии, когда вам нужно что-то изменить. Очевидно, вам вообще не нужно делать никаких копий, если вы ничего не меняете.

Например, у вас может быть неизменный класс, подобный этому:

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;
    }
}
2 голосов
/ 22 марта 2011

Это зависит от семантики неизменяемости, которую вы хотите поддерживать - если вы используете мелкую копию, вы должны быть уверены, что объекты, которыми вы делитесь, также не изменятся, иначе это будет восприниматься как изменение от наблюдателя.Помимо этого, совместное использование объектов может быть очень полезным с точки зрения производительности, то есть эти объекты вам нужны только один раз, а не N раз (см. Также Шаблон веса тела ).

0 голосов
/ 22 марта 2011

Если вы имеете в виду, что копируемые объекты («первый уровень» на графике) являются неизменяемыми, тогда создание мелкой копии является хорошей практикой.

Кроме того, неизменные объекты могут иметь методы-клоны, возвращающие себя, поэтому, если объект, содержащий их, «глубоко скопирован», это действительно будет такая мелкая копия. System.String, например, реализует ICloneable с:

public object Clone()
{
  return this;
}

Лично я бы порекомендовал следующий вариант, который уменьшает необходимость приведения, когда не вызывается через интерфейс:

public class MyImmutableClass : ICloneable
{
  public MyImmutableClass Clone()
  {
    return this;
  }
  ICloneable.Clone()
  {
    return this;
  }
}
...