akkadotnet / Hyperion

Polymorphic serialization for .NET
Apache License 2.0
277 stars 62 forks source link

SerializerOptions.Default doesn't work? #380

Open markjerz opened 1 year ago

markjerz commented 1 year ago

Version Information Hyperion 0.12.2

Describe the bug Using SerializerOptions.Default doesn't work if that's how you create Serializers.

I almost can't believe this to be the case (or I'm losing the plot) because I would have thought others would have hit this straight away as well.

In C#/.Net static variables are instantiated in the order they appear in the source code. (See https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors#remarks) So, as the Default static instance is at the top of SerializerOptions it gets called first.

image

This means that when that constructor is called all the static references are currently null. For example, DefaultValueSerializerFactories is null at the point the constructor is run, resulting in SerializerOptions.ValueSerializerFactories also being null.

This then results in a null ref exception in Serializer.GetSerializerByType when the code attempts to iterate through the value serializer factories during a call to Serialize()

image

It seems like you need to move the Default field down to the bottom of the source code? Or, use a static constructor to explicitly control instantiation?

To Reproduce

var serializer = new Serializer(SerializerOptions.Default);
using var memoryStream = new MemoryStream();
serializer.Serialize(obj, memoryStream);

Expected behavior The object is serialized

Actual behavior Null reference exception

Environment .Net 6