Deserialize в существующие объекты используя стандартный форматер
Источник: habrahabr
mdaemon
Штатная десериализация .net всегда создает граф новых объектов. Это не всегда удобно.
Например если объекты содержат несериализуемые данные, открытые хэндлы и прочее.
Объекты не попадающие в сериализацию могут иметь ссылки на зачитываемые объекты и т.п. Особенно это актуально, если ваша сборка используется еще кем то, и вы не можете решить все подобные случаи при помощи правильного дизайна.
И в конце концов, ради небольшого Undo полностью пересоздавать объекты нерационально.
Поиск не дал готового ответа. Есть не самые простые решения с использованием protobuf и прочих сторонних сериализаторов, но это не всегда применимо. Задача в целом несложная, и мое решение не является чем то выдающимся, но с другой стороны, тем кто впервые столкнется с похожей проблемой - будет проще. Сериализация делается как обычно. Следующие 2 класса решат проблему при десериализации.
[Serializable] public class RealObjectHelper : IObjectReference, ISerializable { Object m_realObject; virtual object getObject(ObjectId id) { //Этот метод должен возвращать ваш объект, return id.GetObject(); } public RealObjectHelper(SerializationInfo info, StreamingContext context) { ObjectId id = (ObjectId)info.GetValue("ID", typeof(ObjectId)); m_realObject = getObject(id); if(m_realObject == null) return; Type t = m_realObject.GetType(); MemberInfo[] members = FormatterServices.GetSerializableMembers(t, context); List deserializeMembers = new List(members.Length); List
При десериализации надо установить Binder, который создаст обертку для десериализации в ваш существующий объект.
BinaryFormatter bf = new BinaryFormatter(null, context); bf.Binder = new RealObjectBinder(YourType.Assembly.FullName, YourType.FullName); bf.Deserialize(memStream);