What steps will reproduce the problem?
Observe the following code snippet:
[ProtoContract]
public class A
{
[ProtoMember(1)]
public string Id { get; set; }
public override bool Equals(object obj) { return Id == ((A)obj).Id; }
}
[ProtoContract]
public class B
{
[ProtoMember(1, AsReference = true)]
public List<A> ListOfA { get; set; }
public override bool Equals(object obj) { return ListOfA.SequenceEqual(((B)obj).ListOfA); }
}
[ProtoContract]
public class C
{
[ProtoMember(1, AsReference = true)]
public List<B> List { get; set; }
public override bool Equals(object obj) { return List.SequenceEqual(((C)obj).List); }
}
class Program
{
static void Main()
{
var m = RuntimeTypeModel.Default;
var a1 = new A { Id = "Abracadabra" };
var a2 = new A { Id = "Focuspocus" };
var a3 = new A { Id = "Abrapocus" };
var b1 = new B { ListOfA = new List<A> { a1, a2 } };
var b2 = new B { ListOfA = new List<A> { a2, a3 } };
var c = new C { List = new List<B> { b1, b2, b2, b1 } };
using (var ms = new MemoryStream())
{
m.Serialize(ms, c);
ms.Position = 0;
var c2 = (C)m.Deserialize(ms, null, typeof(C));
Debug.Assert(c.Equals(c2));
File.WriteAllBytes(@"output.dump", ms.ToArray());
}
}
}
It works very good - output.dump contains only one instance of each of the
strings Abracadabra, Focuspocus and Abrapocus.
Let us now introduce a base type for B:
public interface I { };
public abstract class Abs { };
public class Base { };
[ProtoContract]
public class A
{
[ProtoMember(1)]
public string Id { get; set; }
public override bool Equals(object obj) { return Id == ((A)obj).Id; }
}
[ProtoContract]
public class B : Base
{
[ProtoMember(1, AsReference = true)]
public List<A> ListOfA { get; set; }
public override bool Equals(object obj) { return ListOfA.SequenceEqual(((B)obj).ListOfA); }
}
[ProtoContract]
public class C
{
[ProtoMember(1, AsReference = true)]
public List<Base> List { get; set; }
public override bool Equals(object obj) { return List.SequenceEqual(((C)obj).List); }
}
class Program
{
static void Main()
{
var m = RuntimeTypeModel.Default;
m.Add(typeof(Base), false).AddSubType(1, typeof(B));
var a1 = new A { Id = "Abracadabra" };
var a2 = new A { Id = "Focuspocus" };
var a3 = new A { Id = "Abrapocus" };
var b1 = new B { ListOfA = new List<A> { a1, a2 } };
var b2 = new B { ListOfA = new List<A> { a2, a3 } };
var c = new C { List = new List<Base> { b1, b2, b2, b1 } };
using (var ms = new MemoryStream())
{
m.Serialize(ms, c);
ms.Position = 0;
var c2 = (C)m.Deserialize(ms, null, typeof(C));
Debug.Assert(c.Equals(c2));
File.WriteAllBytes(@"output.dump", ms.ToArray());
}
}
}
What is the expected output? What do you see instead?
I expected the same result, however, this is what one gets:
System.Reflection.TargetException occurred
Message=Object does not match target type.
Source=mscorlib
StackTrace:
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
InnerException:
And the stack trace is:
> protobuf-net.dll!ProtoBuf.Serializers.PropertyDecorator.Read(object value,
ProtoBuf.ProtoReader source) Line 52 + 0x36 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.TypeSerializer.Read(object value, ProtoBuf.ProtoReader source) Line 170 + 0xf bytes C#
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int key, object value, ProtoBuf.ProtoReader source) Line 375 + 0xf bytes C#
protobuf-net.dll!ProtoBuf.ProtoReader.ReadTypedObject(object value, int key, ProtoBuf.ProtoReader reader, System.Type type) Line 534 + 0x1d bytes C#
protobuf-net.dll!ProtoBuf.ProtoReader.ReadObject(object value, int key, ProtoBuf.ProtoReader reader) Line 523 + 0x10 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.SubItemSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(object value, ProtoBuf.ProtoReader source) Line 58 + 0x17 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.TagDecorator.Read(object value, ProtoBuf.ProtoReader source) Line 61 + 0x18 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.TypeSerializer.Read(object value, ProtoBuf.ProtoReader source) Line 168 + 0xf bytes C#
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int key, object value, ProtoBuf.ProtoReader source) Line 375 + 0xf bytes C#
protobuf-net.dll!ProtoBuf.ProtoReader.ReadTypedObject(object value, int key, ProtoBuf.ProtoReader reader, System.Type type) Line 534 + 0x1d bytes C#
protobuf-net.dll!ProtoBuf.BclHelpers.ReadNetObject(object value, ProtoBuf.ProtoReader source, int key, System.Type type) Line 393 + 0x11 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.NetObjectSerializer.Read(object value, ProtoBuf.ProtoReader source) Line 35 + 0x97 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.TagDecorator.Read(object value, ProtoBuf.ProtoReader source) Line 61 + 0x18 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.ListDecorator.Read(object value, ProtoBuf.ProtoReader source) Line 434 + 0x26 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.PropertyDecorator.Read(object value, ProtoBuf.ProtoReader source) Line 53 + 0x18 bytes C#
protobuf-net.dll!ProtoBuf.Serializers.TypeSerializer.Read(object value, ProtoBuf.ProtoReader source) Line 170 + 0xf bytes C#
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int key, object value, ProtoBuf.ProtoReader source) Line 375 + 0xf bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoBuf.ProtoReader reader, System.Type type, object value, bool noAutoCreate) Line 580 + 0x14 bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source, object value, System.Type type, ProtoBuf.SerializationContext context) Line 504 + 0x14 bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source, object value, System.Type type) Line 486 + 0x13 bytes C#
HelloProtoBuf.exe!HelloProtoBuf.Program.Main() Line 54 + 0x5c bytes C#
What version of the product are you using? On what operating system?
v2, rev 424
Please provide any additional information below.
I could have use an abstract base class, an interface or just plain object type
instead of the Base with the same result - it fails. The failures, however, are
in different places.
Thanks.
Original issue reported on code.google.com by mark.kha...@gmail.com on 26 Jun 2011 at 8:41
Original issue reported on code.google.com by
mark.kha...@gmail.com
on 26 Jun 2011 at 8:41