Могу ли я глубоко клонировать объект c #, не помеченный как ICloneable или Serializable? - PullRequest
14 голосов
/ 22 декабря 2008

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

Ответы [ 3 ]

8 голосов
/ 22 декабря 2008

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

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

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

2 голосов
/ 22 декабря 2008

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

Другой вариант - предоставить сериализатор самостоятельно (и сериализовать в Deep-Clone) - «суррогат сериализации». Вот пример VB.

0 голосов
/ 22 декабря 2008

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

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

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

...