Могу ли я глубоко клонировать объект С#, не помеченный ICloneable или Serializable?

У меня есть объект, сам не написанный, что мне нужно клонировать в памяти. Объект не помечен ICloneable или Serializable, поэтому глубокое клонирование через интерфейс или сериализация не будет работать. В любом случае, для глубокого клонирования этого объекта? Возможно, небезопасный вызов API win32?

Ответы

Ответ 1

Интерфейсы FYI, отмеченные как ICloneable, не сохраняются в глубокой скопированности. Разработчик должен реализовать ICloneable, и нет никакой гарантии, которую они будут клонировать. Вы говорите, что объект не реализует ISerializable, но имеет ли он атрибут Serializable?

Создание глубокой копии через двоичную сериализацию - это, пожалуй, один из самых простых методов, о котором я знаю, поскольку вы можете клонировать любой сложный граф в 3-5 строках кода. Другим вариантом будет XmlSerializer, если объект может быть XmlSerialized (вы не указываете какие-либо атрибуты для сериализации или реализации интерфейсов, однако, если есть интерфейс IDictionary, ваш hosed.

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

Ответ 2

"Глубокий" - это сложный бит. Для мелкой копии вы можете использовать отражение для копирования полей (при условии, что ни один из них не является readonly, что является большим предположением), но в противном случае было бы очень сложно заставить это работать (автоматически).

Другой вариант - предоставить сериализатор самостоятельно (и сериализовать до глубокого клонирования) - "суррогат сериализации". Ниже приведен пример VB.

Ответ 3

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

Я не уверен, что в библиотеке отражения промышленного класса, такой как Mono.Cecil, может быть что-то полезное.

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