Если бы MemberwiseClone не существовал, не было бы никаких средств, кроме как с помощью Reflection, для любого наследуемого класса для поддержки операции полиморфного клонирования, за исключением того, что каждый производный класс требовал явного его предоставления.Неспособность производного класса обеспечить операцию клонирования приведет к неожиданному поведению.Например, предположим, что Vehicle, Car и ToyotaCar предоставляют явные методы клонирования, а ToyotaCorolla - нет.Если у кого-то есть объект типа ToyotaCorolla и он пытается его клонировать, получающийся объект будет ToyotaCar.Поскольку существуют ситуации, когда требуется полиморфное клонирование, и было бы неудобно требовать, чтобы каждый производный класс клонируемого класса предоставлял явную поддержку, MemberwiseClone является необходимой частью платформы.
С другой стороны, MemberwiseCloneтакже может быть опасным.Выполнение MemberwiseClone над объектом часто приводит к поломке объекта;попытка использования каких-либо свойств или методов разбитого объекта может привести к повреждению оригинала.
Жаль, что Microsoft не смогла лучше определить хорошую практику для клонирования.Возможно, и не слишком сложно, создать шаблон полиморфного клонирования, который не требует, чтобы унаследованные классы явно что-либо делали, если только они не добавляют поля, требующие специальной обработки, или если вызывающая сторона не ожидает, что объявленный тип возврата метода Clone будетпроизводный класс.В то время как последняя ситуация часто является требованием, отказ от явной реализации необходимого метода приведет к ошибке времени компиляции, а не к ошибочному поведению во время выполнения.
Кстати, Microsoft, похоже, считает, что что-то сбивает с толкупротив мелкого клонирования.НетВызов «Clone» для объекта должен клонировать объект на любую глубину, необходимую для получения его определенной семантики.Клонирование FileCabinet (Of T) должно привести к созданию нового FileCabinet, который для целей методов FileCabinet не зависит от оригинала, но должен содержать те же экземпляры T, что и оригинал.Поскольку целью картотеки является хранение экземпляров T, но ничего с ними не делать, клонирование статива не должно подразумевать клонирование содержимого (но это будет означать клонирование любых массивов, которые сам кабинет использует для хранения содержимого).
Кстати, если бы у меня были мои барабанщики, в .Net был бы интерфейс, реализованный с помощью String и примитивных типов (плюс многие другие), называемый DeepClonableIfMutable.При применении к String или другому примитиву метод DeepCloneIfMutable просто возвращает исходный объект.Определенные пользователем неизменяемые объекты могут реализовывать DeepClonableIfMutable, чтобы вести себя аналогично, тогда как изменяемые объекты будут глубоко клонировать себя и любые вложенные экземпляры DeepClonableIfMutable.