Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deserialize an immutable data structure?

Tags:

c#

yamldotnet

How would I deserialize YAML to a immutable data structure?

e.g. I have this YAML:

Value: SomeString
Number: 99

And this data structure:

public class MyData
{
    public MyData(string value, int number)
    {
        Value = value;
        Number = number;
    }

    public string Value { get; }
    public int Number { get; }
}

For this I'd to use the constructor. So somehow I'd need to first retrieve a Dictionary<string, object> parsed from the YAML respecting my class (so 99 would be int, not string), then scan my type for an appropriate constructor,

like image 694
YamlUser Avatar asked Jul 10 '26 05:07

YamlUser


1 Answers

Although the question doesn't mention it, I'm assuming you are using YamlDotNet (or SharpYaml which is a fork of YamlDotNet)

YamlDotNet doesnt support deserializing into classes that do not have a default constructor - but one option to achieve what you want is to deserialize into an intermediate Builder type that is mutable which can produce the final type. e.g.

public class MyDataBuilder
{
    public string Value { get; set; }
    public int Number { get; set; }
    public MyData Build() => new MyData(Value, Number);
}

And then use something like:

deserializer.Deserialize<MyDataBuilder>(yaml).Build();

You would end up having to create a parallel set of builders for your whole model however, e.g. if MyData had a third parameter of type MyOtherData (I've changed the example to use records instead of classes to make it concise):

public record MyOtherData(string OtherValue);
public record MyData(string Value, int Number, MyOtherData otherData);

In which case we would need another Builder:

public class MyOtherDataBuilder 
{
    public string OtherValue { get; set; }
}

And MyDataBuilder would look like:

public class MyDataBuilder
{
    public string Value { get; set; }
    public int Number { get; set; }
    public MyOtherDataBuilder MyOtherData { get; set; }
    public MyData Build() => new MyData(Value, Number, MyOtherData.Build());
}
like image 57
Brian Flynn Avatar answered Jul 28 '26 18:07

Brian Flynn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!