Using protobuf-net v2 build 668, I’m trying to serialize/deserialize a class which contains a member defined as an interface while doing on-the-fly conversions at the same time. Normally, the surrogate approach would work just fine but since C# doesn’t allow user-defined conversions for interfaces, I can’t define the conversions.
Thanks,
namespace ProtoBufNetTest
{
using System.Diagnostics;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;
class Program
{
static void Main()
{
RuntimeTypeModel.Default.Add(typeof(IDummy), false)
.SetSurrogate(typeof(DummySurrogate));
var container = new Container { Data = new Dummy { Positive = 3 } };
using (var file = File.Create("test.bin"))
{
Serializer.Serialize(file, container);
}
using (var file = File.OpenRead("test.bin"))
{
container = Serializer.Deserialize<Container>(file);
Debug.Assert(container.Data.Positive == 3);
}
}
}
// Outside of the project, cannot be changed
public interface IDummy
{
int Positive { get; set; }
}
[ProtoContract]
public class Container
{
[ProtoMember(1)]
public IDummy Data { get; set; }
}
public class Dummy : IDummy
{
public int Positive { get; set; }
}
[ProtoContract]
class DummySurrogate
{
[ProtoMember(1)]
public int Negative { get; set; }
// Does not compile : user-defined conversions to or from an interface are not allowed
public static explicit operator IDummy(DummySurrogate value)
{
return value == null ? null : new Dummy { Positive = -value.Negative };
}
// Does not compile : user-defined conversions to or from an interface are not allowed
public static explicit operator DummySurrogate(IDummy value)
{
return value == null ? null : new DummySurrogate { Negative = -value.Positive };
}
// Fake attribute, does not exist but could work if it did
[ProtoConvertFrom]
public static IDummy From(DummySurrogate value)
{
return value == null ? null : new Dummy { Positive = -value.Negative };
}
// Fake attribute, does not exist but could work if it did
[ProtoConvertTo]
public static DummySurrogate To(IDummy value)
{
return value == null ? null : new DummySurrogate { Negative = -value.Positive };
}
}
}
In the current build: no, there is not.
However, in the next build, this works fine:
[ProtoContract]
class DummySurrogate
{
[ProtoMember(1)]
public int Negative { get; set; }
[ProtoConverter]
public static IDummy From(DummySurrogate value)
{
return value == null ? null : new Dummy { Positive = -value.Negative };
}
[ProtoConverter]
public static DummySurrogate To(IDummy value)
{
return value == null ? null : new DummySurrogate
{ Negative = -value.Positive };
}
}
Basically, a static
method marked [ProtoConverter]
takes precedence over an implicit
or explicit
conversion operator that is defined, with the further advantage that [ProtoConverter]
methods are not subject to the same syntactic rules as operators. It is not necessary to define separate *To
/ *From
attributes, as the intent is clear from the signature.
As a side note: the attributes on Dummy
are unnecessary and are never used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With