anerjan / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
Other
0 stars 0 forks source link

Impossible serialize a complex hierarchy with v2 r444 #231

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Given this hierarchy of class:

[ProtoContract]
[ProtoInclude(10, typeof(Sale))]
public abstract class Doc
{
    [ProtoMember(1)]
    public int Numero { get; set; }
}

[ProtoContract]
[ProtoInclude(10, typeof(Receipt))]
public abstract class Sale : Doc
{
    protected Sale()
    {
        Dets = new List<Det>();
    }

    [ProtoMember(1, DynamicType = true, AsReference = true)]
    public List<Det> Dets { get; private set; }
}

[ProtoContract]
public class Receipt : Sale
{}

[ProtoContract]
[ProtoInclude(10, typeof(Item))]
[ProtoInclude(11, typeof(Subtotal))]
[ProtoInclude(12, typeof(Adj))]
public abstract class Det
{
    [ProtoMember(1)]
    public string Desc { get; set; }
}

[ProtoContract]
public class Subtotal : Det, IRefs<Det, Det>
{
    public Subtotal()
    {
        Refs = new List<IRef<Det, Det>>();
    }

    [ProtoMember(1, DynamicType = true, AsReference = true)]
    public List<IRef<Det, Det>> Refs { get; private set; }

}

[ProtoContract]
public class Item : Det, IRefs<Det, Det>
{
    public Item()
    {
        Refs = new List<IRef<Det, Det>>();
    }

    [ProtoMember(1, DynamicType = true, AsReference = true)]
    public List<IRef<Det, Det>> Refs { get; private set; }
}

[ProtoContract]
public class Adj : Det, IRefs<Det, Det>
{
    public Adj()
    {
        Refs = new List<IRef<Det, Det>>();
    }

    [ProtoMember(1, DynamicType = true, AsReference = true)]
    public List<IRef<Det, Det>> Refs { get; private set; }
}

public interface IRefs<T, U> 
    where T: Det 
    where U :Det
{
    List<IRef<T, U>> Refs { get; }
}

public interface IRef<out T, out U>
    where T : Det
    where U : Det
{
    T To { get; }
    U By { get; }
}

[ProtoContract]
[ProtoInclude(10, typeof(SubRef<Item>))]
[ProtoInclude(11, typeof(AdjRef<Item>))]
public abstract class Ref<T, U> : IRef<T, U>
    where T : Det
    where U : Det
{
    [ProtoMember(1, AsReference = true, DynamicType = true)]
    public T To { get; set; }
    [ProtoMember(2, AsReference = true, DynamicType = true)]
    public U By { get; set; }
}

[ProtoContract]
[ProtoInclude(10, typeof(SubItemRef))]
public abstract class SubRef<U> : Ref<Subtotal, U> where U : Det
{
}

[ProtoContract]
public class SubItemRef :SubRef<Item>
{
}

[ProtoContract]
[ProtoInclude(10, typeof(AdjItemRef))]
public abstract class AdjRef<U> : Ref<Adj, U> where U : Det
{
}

[ProtoContract]
public class AdjItemRef :AdjRef<Item>
{
}

This test falis:

var doc = new Receipt {Numero = 3};
var item = new Item {Desc = "item"};
var adj = new Adj { Desc = "Adj" };
var subTot = new Subtotal {Desc = "sutotal"};

var refference = new SubItemRef {By = item, To = subTot};
item.Refs.Add(refference);
subTot.Refs.Add(refference);

var ref2 = new AdjItemRef {By = item, To = adj};
item.Refs.Add(ref2);
adj.Refs.Add(ref2);

doc.Dets.Add(item);
doc.Dets.Add(adj);
doc.Dets.Add(subTot);

var docCloned = Serializer.DeepClone(doc);
Assert.IsTrue(((Item)docCloned.Dets[0]).Refs[0].By != null);

I have tried any combination of Proto Attribute.

Original issue reported on code.google.com by simionat...@gmail.com on 9 Sep 2011 at 3:52