2

My C# class has the following structure

public class Example
{
    public static Example Instance1 = new Example (0, "A");
    public static Example Instance2 = new Example (1, "B");
    protected Example(int value, string name)
    {
        this.value = value;
        this.name = name;
    }
    private int value;
    private string name;
 }

Now I am trying to serialize Example.Instance1 as follows

var serializedVariable = JsonConvert.SerializeObject(Example.Instance1);

var OriginalVariable = JsonConvert.DeserializeObject<Example>(serializedVariable);

But it throws the exception that it does not have the constructor specified for JSON, but the value and name are lost in the deserialized version.

Now I added a parameter called [JsonConstructor] for the constructor. It does deserialize successfully but the name and value are lost in the deserialized class.

Can you please help me with, how to serialize such class instances?

Nik
  • 1,780
  • 1
  • 14
  • 23
  • On another note, What keeps your example from creating an infinite loop of initializing objects? – S. Walker Nov 04 '17 at 01:47
  • 2
    The reason the values are not serialized is because they not ***public properties***, why the hell do you want to hide them? Just expose them as public properties and you will be good to go. You can also use `JsonPropertyAttribute` on private members to allow serialization on them. – King King Nov 04 '17 at 03:28
  • Try and create an instance of that class without calling the static members and you will not be able to. If you cannot, then the deserializer cannot do it as well. – CodingYoshi Nov 04 '17 at 04:01
  • 1
    You need to mark the private/protected members you wish to serialize (here `name` and `value`) with `[JsonProperty]` as explained [here](https://stackoverflow.com/a/25950535/3744182) and [here](https://stackoverflow.com/q/32008869). [Fiddle](https://dotnetfiddle.net/Yk3YAe). And you've already found the `[JsonConstructor]` attribute, whose use is explained [here](https://stackoverflow.com/a/23017892/3744182). So, duplicate? – dbc Nov 04 '17 at 17:26

1 Answers1

1

The issue is that your Example class does not have a default constructor. When you do not define a constructor in the class definition, the compiler will provide you with one implicitly
(see this answer); however, if do define an overloaded constructor (as you did), the compiler will no longer provide you with a default constructor.

In order to deserialize and instantiate and instance of a class (which is all done through reflection), your class must have a default constructor. See this question.

The code below should now work as expected:

public class Example
{
    public static Example Instance1 = new Example (0, "A");
    public static Example Instance2 = new Example (1, "B");
    //Must have this default constructor!
    protected Example()
    {//... Add code if needed
    }
    protected Example(int value, string name)
    {
        this.value = value;
        this.name = name;
    }
    private int value;
    private string name;
}
Nik
  • 1,780
  • 1
  • 14
  • 23
  • static members are shared and initialized ***just once***, so there would not be any infinitive recursion here. – King King Nov 04 '17 at 03:21
  • @KingKing, please note that I did not mean that there is infinite recursion on initialization, I meant there is the potential for it when using an instance of the class. If you instantiate a class, use your debugger to inspect the object. As you look at `Instance1`, then inspect its `Instance1` variable, and the next, and onto infinity. The potential trouble is if you have code that accesses these fields recursively, then you will end up with stack overflow. I will modify my answer to clarify this. – Nik Nov 04 '17 at 03:31
  • it's totally fine if the member is ***static*** - that's one important point, if he misses the *static* declaration, of course infinite recursion could occur. – King King Nov 04 '17 at 03:33
  • 1
    @KingKing, you're right, the problem I am thinking of is completely tangential and does not add any value to this specific question. I will remove that portion of the answer. Thank you for pointing this out. – Nik Nov 04 '17 at 03:39