1
votes

I have the following code, attempting to de/serialize an "Attribute" class, which is basically a name/value pair where the type of the value is unknown (object):

[ProtoContract]
[ProtoInclude(100, typeof(ValueAttr))]
public abstract class BaseAttr
{
    protected BaseAttr(string name) { _name = name; }
    public string Name { get { return _name; } }
    public abstract object Value { get; }
    public abstract ValueAttr Evaluate();
    [ProtoMember(1)]
    private readonly string _name;
}

[Serializable]
[ProtoContract]
public class ValueAttr : BaseAttr
{
    public ValueAttr(string name, object value) : base(name)
    { _value = value; }

    public override ValueAttr Evaluate() { return this; }

    public override object Value { get { return _value; } }
    [ProtoMember(1, DynamicType = true)]
    protected object _value;
}

[Serializable]
public class Attr<T> : ValueAttr
{
    public Attr(string name, T value) : base(name, value) { _value = value; }
}

What I'm trying to achieve is protobuf-net "native" serialization for the native .NET types, and to default to binary .NET serialization for all other types (assuming they're Serializable, of course). I thought DynamicTypecan help me with that, until I found out that the "Dynamic" part refers only to contracted types.

What is the most efficient way (in time and memory) to do this? Is it using the ValueWrapper example in protobuf.net? If so, how do I implement the defualt .NET serialization?

Thanks!

1

1 Answers

1
votes

protobuf-net doesn't have any code in it that would switch to BinaryFormatter (although it does have some code to allow itself to be used by BinaryFormatter). But if this is the root object, you should be able to ask the model itself when you serialize:

var model = RuntimeTypeModel.Default;
if (model.CanSerialize(type))
{
    // TODO: add some kind of token to indicate serializer used
    model.Serialize(dest, obj);
}
else if(type.IsSerializable)
{
    // TODO: add some kind of token to indicate serializer used
    new BinaryFormatter().Serialize(dest, obj);
}
else { /* PANIC!!!! */ }

This won't help you for child objects; ultimately, protobuf-net wants to understand the model.