Tom Warner Tom Warner - 10 months ago 50
C# Question

Serializing a reference to a static readonly member

I have a piece of code that looks something like this:

public static class MyStaticClass
public static readonly MyObject1 object1 = new MyObject1();

public class MyOtherClass
public MyObject1 Obj { get; } = MyStaticClass.object1;

When deserializing (using default binary serialization) an instance of MyOtherClass, Obj is no longer the same object as MyStaticClass.object1. Is there any way to automatically retain that reference, or am I simply going to have to reconstruct it via a string or some other identifier? If so, what would be the recommended way to cleanly rebuild that reference?

Answer Source

Is there any way to automatically retain that reference

That depends on your definition of "automatically", but assuming you mean "without writing any additional code", the answer is "no".

Serialization deals with data, not objects. When you deserialize the object, all that the stock deserialization implementations know is the data that was stored. Which is as it should be; a general-purpose deserialization implementation wouldn't even know where to look to match an object like that and use an existing reference, so it'd have to search the entire in-memory object graph from all roots.

You will need to provide a mechanism to deal with this explicitly. Depending on what serialization method you're using, you may be able to customize the entire process so that you don't have to serialize the entire MyObject1 data, but instead just store some kind of marker that your customized deserialization can use to signify the original object.

Alternatively, your customization could just rely on MyObject1 implementing some type of equality, so that you can compare the deserialized object and replace its reference with the "stock" reference if the two objects are equal.

If you're using a serialization method that supports the IObjectReference.GetRealObject() mentioned in the comments, that would work too.

But whatever you do, you're going to have to do it yourself. (Or use a third-party library that supports a feature like that out of the box…I'm not aware of any, but that doesn't mean it doesn't exist.)