kalki
kalki

Reputation: 526

Protobuf-net Runtime serialization

[ProtoContract]
public abstract class Animal
{
    [ProtoMember(1)]
    public abstract string Type { get; set; }
    [ProtoMember(2)]
    public string Name { get; set; }
    [ProtoMember(3)]
    public int Likeability { get; set; }
}

public class Cat : Animal
{
    public override string Type { get; set; }
    public int Friendliness { get; set; }

    public override string ToString()
    {
        return String.Format("Type : {0}, Name : {1}, Likeability : {2}, Friendliness : {3}", Type, Name, Likeability, Friendliness);
    }
}

use case i.e.

var animal = new Cat() { Name = "Whiskers", Friendliness = 10 , Type = "cat", Likeability = 5};
var model = TypeModel.Create();
model[typeof(Animal)].AddSubType(4, typeof(Cat));
model[typeof(Cat)].AddField(1, "Friendliness");
var typeModel = model.Compile();

var memoryStream = new MemoryStream();
typeModel.Serialize(memoryStream, animal);

var deserializedCat = new Cat() { Name = "PusPus" };
memoryStream.Seek(0, SeekOrigin.Begin);
var deserializedCat1 = typeModel.Deserialize(memoryStream, deserializedCat, typeof(Cat));
Console.WriteLine("deserializedCat : hash : " + deserializedCat.GetHashCode() + "\n" + deserializedCat);
Console.WriteLine("deserializedCat1 : hash : " + deserializedCat1.GetHashCode() + "\n" + deserializedCat1);

Is the above use case correct for reusable runtime serialization or should one explicitly map the "Cat" ignoring the "Animal" and Also a bit confused w.r.t "ComplileInPlace" how does it differ from Compile ?

Upvotes: 1

Views: 1277

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1064104

In terms of mapping at runtime, that looks fine. Does it work as expected? i.e. do you get a cat back? and both the Animal and Cat members?

Differences in the Compile* methods:

  • CompileInPlace() makes the existing model, such that future calls to model.Serialize(...) will use the serialized form. Normally this is automatic anyway the first time each type is required, but this allows it to be prepared ahead of time; the "in place" approach also has extra features - it can access private members, and it can do extra stack tricks for small performance tweaks - but it is not available on all platforms
  • Compile(string,string) allows you to compile the model to a separate dll file, which can be referenced and used for fully-static serialization (i.e. no reflection at runtime)
  • Compile() does something like that, but creates an instance of a TypeModel built from the model, without a separate dll file

In most cases, CompileInPlace() is what you are after - although you don't need to do anything at all, since it will usually automatically compile-in-place when needed

Upvotes: 2

Related Questions