1
class MyObj
{
    private int _Max;
    public object Max
    {
        get
        {
            return (int)_Max;
        }
        set
        {
            _Max = (int)value;
        }
    }
}

Program.cs

MyObj obj1 = new MyObj(100);
string json = JsonConvert.SerializeObject(obj1, Formatting.Indented);
obj1.Max = 200;
MyObj obj2 = JsonConvert.DeserializeObject<MyObj>(obj1);

When ran, it crashed on the last line of Program.CS (Deserialize) while doing a Set on the Max property

An exception of type 'System.InvalidCastException' occurred in Supremacy.exe but was not handled in user code

Why does my Set to 200, works but the Deserialize does not? I debugged and the 200 value that is tried to be Set into obj2 is an object containing an int.

If there is no setter on max, Program.cs run properly

Explain me why and how to fix it :)

PS: I'm using box/unboxing because MyObj is part of a hierarchy and it could be any primitive type that would be used as a Max.

PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
Fawar
  • 735
  • 2
  • 11
  • 32

2 Answers2

1

To solve the issue of exception use Convert.ToInt32:

public object Max
{
    get
    {
        return (int)_Max;
    }
    set
    {
        _Max = Convert.ToInt32(value);
    }
}

I think the issue happens because after deserializing the value compiler doesn't know if it's originally been an integer. All it has is this string:

{
  "Max": 100
}

So the value of 100 is consumed as a string. And .Net has a prevention mechanism that does not allow boxing one type (e.g. decimal) and unboxing to a different type (e.g. integer). Here the cast happens from string to integer so it's not allowed as well. More details on that in this answer.

Community
  • 1
  • 1
PiotrWolkowski
  • 8,408
  • 6
  • 48
  • 68
0

Flagging a line...

return (int)_Max;

Line 5 should be

return (object)_Max;

because on line 1, Max is object.