views:

43

answers:

1

Hello,

The following test fails with this error:

"System.InvalidOperationException : No suitable Default IB encoding found."

[ProtoContract]
public class A
{
    [ProtoMember(1)]
    public IB B { get; set; }
}

public interface IB
{
}

[ProtoContract]
public class B : IB
{
    [ProtoMember(1)]
    public int SomeProperty { get; set; }
}

[TestFixture]
public class TestFixture
{
    [Test]
    public void Test()
    {
        var a = new A {B = new B()};
        using (var m = new MemoryStream())
        {
            Serializer.Serialize(m, a);
        }
    }
}

I'm using this implementation of Protobuf.net :

http://code.google.com/p/protobuf-net/

Did I miss something? thanks you very much.

A: 

That is a common feature of contract-based serializers, including XmlSerializer, etc (i.e. those that don't include type metadata for every object).

There are a few things that make this tricky:

  • during deserialization, what type would it create for A.B?
  • during serialization, the "what is the current object" bears little relationship to the contract
    • in particular it gets very messy if the type implements multiple interfaces

This is a scenario I want to get something working for in "v2" though (but maybe not quite for release); I'm thinking:

  • either A.B must be non-null to start with (i.e. A decides the type of A.B), or a default implementation must be specified somewhere
  • interface-based is mutually exclusive vs. inheritance; when using interfaces there can be no inheritance support
  • all interface usage would be via properties, never fields (obviously)

Alternatively, and perhaps more suited to the scenario presented, we could use something like [ProtoInclude] to indicate the concrete types.

But within those limits I think something is possible. But not today.

Marc Gravell