Serialization issues while using inheritance with the System.Text.Json lib

40 Views Asked by At

I am replacing the Newtonsoft library by the System.Text.Json and the result is quite different. I am using inheritance and have made an example for simplicity.

public interface ID
{
    int DProp { get; set; }
}

public class D : ID
{
    public int DProp { get; set; }
}

public interface IC
{
    IEnumerable<IY> CList { get; set; }
}

public class C : D, IC
{
    public IEnumerable<IY> CList { get; set; }
}

public interface IB : IC
{    
    IEnumerable<IZ> BList { get; set; }
}
 
public class B : C, IB
{
    public IEnumerable<IZ> BList { get; set; }
}

public interface IA
{
    IEnumerable<IB> BList { get; set; }
 
    string SomeProp { get; set; }
}

public class A : IA
{ 
    public IEnumerable<IB> BList { get; set; }

    public string SomeProp { get; set; }
}

//Creating objects
var yList = new List<IY>()
{
    new Y() { YProp = 2 },
};
var zList = new List<IZ>()
{
    new Z() { ZProp = 2 },
};
var bList = new List<IB>
{
    new B { CList = yList, BList = zList, DProp = 1 },
};
IA a = new A();
a.BList = bList;
a.SomeProp = "123";

var jsonSerialized = JsonSerializer.Serialize(a);

And the jsonSerialized result is:

{
    "BList": [
        {
            "BList": [
                {
                    "ZProp": 2
                }
            ],
            "CList": [
                {
                    "YProp": 2
                }
            ]
        }
    ],
    "SomeProp": "123"
}

The question is, why is the DProp not present in the output? B derives from C and C from D.

2

There are 2 best solutions below

2
Caveman74 On BEST ANSWER

I think you have misunderstood the "inheritance" of interfaces.

blist is defined as IEnumerable<IB>.

So you have the following interface "inheritance": IB implements IC.

To include ID.Prop you need IC to implement ID.

0
Gerry Schmitz On
var bList = new List<IB>
{
    new B { CList = yList, BList = zList, DProp = 1 },
};

You've created a "list of IB" while instantiating "B". Without re-casting you've lost access to what B inherits; i.e. DProp.