I have a problem serializing derived classes using protobuf-net. I don't know if it is because it is not supported, or I am doing something wrong.
I have a generic base class (which I can serialize directly) and then i make a specialization of this, but this one I can't serialize. The following is the code for the two classes and a example of usage. Am i doing something wrong?
Edit
Added restriction to the generic types
Base
[ProtoBuf.ProtoContract]
public class Base<TKey, TValue>
where TKey : Key
where TValue : Key
{
[ProtoBuf.ProtoMember(1)]
public Dictionary<TKey, Dictionary<TKey, TValue>> Data { get; set; }
[ProtoBuf.ProtoMember(2)]
public TValue DefaultValue { get; set; }
public Base()
{
this.Data = new Dictionary<TKey, Dictionary<TKey, TValue>>();
}
public Base(TValue defaultValue)
: this()
{
this.DefaultValue = defaultValue;
}
public TValue this[TKey x, TKey y]
{
get
{
try { return this.Data[x][y]; }
catch { return this.DefaultValue; }
}
set
{
if (!this.Data.ContainsKey(x))
this.Data.Add(x, new Dictionary<TKey, TValue> { { y, value } });
else
this.Data[x][y] = value;
}
}
}
Key class
public abstract class Key
{
}
Specialized key
[ProtoBuf.ProtoContract]
public class IntKey : Key
{
[ProtoBuf.ProtoMember(1)]
public int Value { get; set; }
public IntKey() { }
public override int GetHashCode()
{
return this.Value.GetHashCode();
}
public override bool Equals(object obj)
{
if (ReferenceEquals(obj, null)) return false;
if (ReferenceEquals(obj, this)) return true;
var s = obj as IntKey;
return this.Value.Equals(s.Value);
}
}
Specialized class
[ProtoBuf.ProtoContract]
public class IntWrapper<TKey> : Base<TKey, IntKey>
where TKey : Key
{
public IntWrapper()
: base() { }
public IntWrapper(IntKey defaultValue)
: base(defaultValue) { }
}
An example of usage
var path = @"C:\Temp\data.dat";
var data = new IntWrapper<IntKey>(new IntKey { Value = 0 }); // This will not be serialized
for(var x = 0; x < 10; x++)
{
for(var y = 0; y < 10; y++)
data[new IntKey { Value = x }, new IntKey { Value = y }] = new IntKey { Value = x + y };
}
using (var fileStream = new FileStream(path, FileMode.Create))
{
ProtoBuf.Serializer.Serialize(fileStream, data);
}