Интерфейс ICloneable
сам по себе не очень полезен, то есть фактически не так много ситуаций, когда полезно знать, что объект является клонируемым, не зная ничего о нем. , Это очень отличается от ситуации, например, IEnumerable
или IDisposable
; Во многих ситуациях полезно принять IEnumerable
, не зная ничего, кроме как перечислить его.
С другой стороны, ICloneable
может быть полезно при применении в качестве общего ограничения вместе с другими ограничениями. Например, базовый класс может с пользой поддерживать ряд производных, некоторые из которых могут быть полезны для клонирования, а некоторые нет. Если сам базовый тип предоставляет открытый интерфейс клонирования, то любой производный тип, который не может быть клонирован, будет нарушать принцип замещения Лискова. Чтобы избежать этой проблемы, нужно иметь поддержку клонирования базовых типов с использованием метода Protected и разрешать производным типам реализовывать общедоступный интерфейс клонирования по своему усмотрению.
Как только это будет выполнено, метод, который хочет принять объект типа WonderfulBase
и должен иметь возможность клонировать его, может быть закодирован для принятия объекта WonderfulBase, который поддерживает клонирование (используя параметр универсального типа с ограничения базового типа и ICloneable
). Хотя интерфейс ICloneable
сам по себе не будет указывать на глубокое или поверхностное клонирование, документация для WonderfulBase
будет указывать, должно ли клонируемое WonderfulBase
быть клонировано глубоко или неглубоко. По сути, интерфейс ICloneable
не будет выполнять ничего, что не может быть достигнуто путем определения ICloneableWonderfulBase
, за исключением того, что ему не придется определять разные имена для каждого другого клонируемого базового класса.