Почему следует использовать ICloneable в С#?

Можете ли вы объяснить мне, почему я должен наследовать от ICloneable и реализовать метод Clone()?

Если я хочу сделать глубокую копию, не могу ли я просто реализовать свой метод? Скажем, MyClone()?

Зачем мне наследовать от ICloneable? Каковы преимущества? Это просто вопрос, что код "более читабельный"?

Ответ 1

Вы не должны. Корпорация Майкрософт рекомендует не применять ICloneable, поскольку нет четкого указания интерфейса, если ваш метод Clone выполняет "глубокий" или "мелкий" клон.

См. это сообщение в блоге от Brad Abrams еще в 2003 году (!) для получения дополнительной информации.

Ответ 2

Интерфейс ICloneable сам по себе не очень полезен, то есть очень мало ситуаций, когда полезно знать, что объект клонирован, не зная ничего о нем Это. Это совсем другая ситуация, например, IEnumerable или IDisposable; существует много ситуаций, когда полезно принимать IEnumerable, не зная ничего, кроме как перечислить его.

С другой стороны, ICloneable может быть полезна при применении в качестве общего ограничения наряду с другими ограничениями. Например, базовый класс может с пользой поддерживать ряд производных, некоторые из которых могут быть полезны для клонирования, а некоторые из них не могут. Если базовый тип сам отображал открытый интерфейс клонирования, то любой производный тип, который не мог быть клонирован, нарушал бы принцип замены Лискова. Способ избежать этой проблемы состоит в том, чтобы клонирование поддержки базового типа с использованием защищенного метода и позволить производным типам реализовывать открытый интерфейс клонирования по своему усмотрению.

Как только это было выполнено, метод, который хочет принять объект типа WonderfulBase и должен быть способен клонировать его, может быть закодирован, чтобы принять объект WonderfulBase, который поддерживает клонирование (с использованием параметра типового типа с базового типа и ICloneable). Хотя интерфейс ICloneable сам по себе не указывает на глубокое или мелкое клонирование, документация для WonderfulBase указывает, должен ли клонируемый WonderfulBase быть глубоким или мелко-клонированным. По сути, интерфейс ICloneable не выполнил бы ничего, что не было бы достигнуто, определяя ICloneableWonderfulBase, за исключением того, что он избегал бы определять разные имена для каждого другого клонируемого базового класса.

Ответ 3

ICloneable является одним из тех артефактов в BCL, который был спорным. Нет реальной причины, чтобы ИМХО ее реализовала. С учетом сказанного, если я собираюсь создать метод clone, я реализую ICloneable, и я предоставляю свою собственную типичную версию Clone.

Проблема с ICloneable никогда не указана, если Clone была мелкой или глубокой копией, которая очень отличается. Тот факт, что нет ICloneable<T>, может быть показателем в мыслях Microsoft о ICloneable

Ответ 4

Мэтт прав, не используйте его. Создайте свой собственный метод Copy() (или аналогичное имя) и полностью очистите свой публичный API независимо от того, создает ли ваш метод глубокую или мелкую копию вашего объекта.