Почему я должен реализовать ICloneable в C#?

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

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

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

4 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам