1

I have an "options" object that I'm trying to save to Settings

public class MainWindow
{
    public MyOptions MyOptions => (MyOptions)DataContext;

    public MainWindow()
    {
        InitializeComponent();

        DataContext = Settings.Default.MyOptions ?? new MyOptions();
    }

    private void OnOptionsChanged(object sender, PropertyChangedEventArgs e)
    {
        Settings.Default.MyOptions = MyOptions;
        Settings.Default.Save();
    }

    // etc.
}

MyOptions contains (among other things) a struct-value

public class MyOptions
{
    private MyStruct _myStruct;

    public MyOptions()
    {
        _myStruct = someDefaultValue;
    }

    // etc.
}

MyStruct contains only a single int:

public struct MyStruct
{
    private readonly int _someValue;
    public MyStruct(int someValue)
    {
        _someValue = someValue;
    }

    // etc.
}

When I make the call to Settings.Default.MyOptions = MyOptions;, all the values are set correctly, including myStruct.

However, when I restart the program and load the options with DataContext = Settings.Default.MyOptions, all the values are correctly loaded except for _myStruct, which defaults to 0!

According to everything I've read, this code should work. I've tried adding the [Serializable] attribute to both the class/struct, as well as implementing ISerializable (which I shouldn't have to do), but neither helped. What am I missing?

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
  • 1
    My first guess would be that it's not `struct` that's the problem, it's `readonly`. Deserialisation works by creating an instance of an object and then setting its fields. I can imagine why that wouldn't work with `readonly` fields. But this is completely untested guesswork. –  Dec 27 '16 at 20:38
  • Have you tried make someValue public, and make constructor parameterless? – gabba Dec 27 '16 at 20:39

2 Answers2

2

Settings are serialized as XML, which has a limitation of excluding readonly members.

Removing readonly qualifier should fix this problem:

public struct MyStruct {
    internal int _someValue;
    public MyStruct(int someValue) {
        _someValue = someValue;
    }
}
Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Try this struct, in my test case it serialized right way:

public struct MyStruct
{
    public int SomeValue { get; set; }
}
gabba
  • 2,815
  • 2
  • 27
  • 48
  • So `private` values can be serialized in classes but not structs? Is this documented anywhere? EDIT: I believe my question is answered [here](http://stackoverflow.com/questions/445915/deep-xml-serialize-a-struct-options). It seems there's no good way to do deep-serialization of objects using `Settings`. Ugh, what a ridiculous design oversight. – BlueRaja - Danny Pflughoeft Dec 27 '16 at 21:17