Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I deserialize into an existing object - C#

In C#, after serializing an object to a file how would I deserialize the file back into an existing object without creating a new object?

All the examples I can find for custom serialization involve implementing a constructor that will be called upon deserialization which is exactly what I want except that I don't want the function to be a constructor.

Thanks!

like image 286
rob Avatar asked Dec 11 '11 20:12

rob


People also ask

How do you deserialize data?

Deserialization is the process of reconstructing a data structure or object from a series of bytes or a string in order to instantiate the object for consumption. This is the reverse process of serialization, i.e., converting a data structure or object into a series of bytes for storage or transmission across devices.

How does JSON deserialize work?

Deserialization is the process of reversing a String from a previously serialized format. This coverts the serialized String into a format that allows its Data Structure properties to be accessible to manipulation.

What is JSON deserialize?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).


2 Answers

Some serializers support callbacks; for example, both BinaryFormatter and DataContractSerializer (and protobuf-net, below) allow you to specify a before-serializaton callback, and since they skip the constructor, this may well be enough to initialize the object. The serializer is still creating it, though.


Most serializers are fussy about wanting to create the new object themselves, however some will allow you to deserialize into an existing object. Well, actually the only one that leaps to mind is protobuf-net (disclosure: I'm the author)...

This has 2 different features that might help here; for the root object (i.e. the outermost object in a graph) you can supply the existing object directly to either the Merge methods (in v1, also present in v2 for compatibility), or (in v2) the Deserialize methods; for example:

var obj = Serializer.Merge<YourType>(source, instance);

However, in a larger graph, you might want to supply other objects yourself (than just the root). The following is not exposed on the attribute API, but is a new feature in v2:

RuntimeTypeModel.Default[typeof(SomeType)].SetFactory(factoryMethod);

where factoryMethod can be either the name of a static method in SomeType (that returns a SomeType instance), or can be a MethodInfo to any static method anywhere. The method can additionally (optionally) take the serialization-context as a parameter if you want. This method should then be used to supply all new instances of SomeType.


Note: protobuf-net is not quite the same as BinaryFormatter; for best effect, you need to tell it how to map your members - very similar to marking things as [DataMember] for WCF/DataContractSerializer. This can be attributes, but does not need to be.

like image 74
Marc Gravell Avatar answered Oct 02 '22 13:10

Marc Gravell


If it's just a matter of copying a few fields, I would avoid all the trouble and take the simple route - deserialize into a new instance, then copy the appropriate fields to the existing instance. It will cost you a couple of extra copies, but you'll save a lot of time on debugging.

like image 42
zmbq Avatar answered Oct 02 '22 12:10

zmbq