c# - protobuf-net use a string type as surrogate -
i trying serialize protobuf format c# class has properties on domain specific types. these types should handled value types.
i using protobuf.net.
an example
[protocontract] public class testclass { [protomember(1)] public string stringproperty { get; set; } [protomember(2)] public domaintypetobehandldedasstring domaintypetobehandldedasstring { get; set; } } public class domaintypetobehandldedasstring { public string value { get; set; } public static implicit operator string(domaintypetobehandldedasstring domaintype) { return domaintype?.value; } public static implicit operator domaintypetobehandldedasstring(string s) { return new domaintypetobehandldedasstring {value = s}; } } in serialized message not want people care domaintypetobehandldedasstring. want them see string , send string.
so tried doing this:
var model = protobuf.meta.runtimetypemodel.default; model.add(typeof(domaintypetobehandldedasstring), false).setsurrogate(typeof(string)); but fails exception:
system.argumentexception: 'repeated data (a list, collection, etc) has inbuilt behaviour , cannot used surrogate' is there way specify custom serializer such class? , should said there domain types should treated int or other value types. not string.
thanks
edit
i tried in addition:
[protocontract] public class testclass { [protomember(1)] public string stringproperty { get; set; } public domaintypetobehandldedasint domaintypetobehandldedasint { get; set; } } [protocontract] public class domaintypetobehandldedasint : iconvertible { [protomember(1)] public int value { get; set; } public static implicit operator int(domaintypetobehandldedasint domaintype) { return domaintype?.value ?? 0; } public static implicit operator domaintypetobehandldedasint(int s) { return new domaintypetobehandldedasint { value = s }; } public int toint32(iformatprovider provider) { return value; } //all rest throw notimplementedexception } i added type runtimemodel this:
var model = protobuf.meta.runtimetypemodel.default; model[typeof(testclass)].add(2, "domaintypetobehandldedasint", typeof(int32), null); and resulted in .proto file this:
syntax = "proto3"; package protobufferserializertest; message testclass { string stringproperty = 1; repeated int32 domaintypetobehandldedasint = 2 [packed = false]; } but not want repeated , don't need [packed = false] either.
that's interesting question. @ moment, answer "no, isn't supported", but: following is supported, if enable allowparseabletypes (on runtimetypemodel instance - runtimetypemodel.default instance behind serializer.* methods):
public class domaintypetobehandldedasstring { public string value { get; set; } public override string tostring() => value; public static domaintypetobehandldedasstring parse(string s) => new domaintypetobehandldedasstring { value = s }; } basically, looks public static {type} parse(string) pattern. but: agree better express explicitly, , "surrogate string" nice way convey this. open adding direct support have in question, isn't there today , need code changes. not many, probably, since essentials of feature exist via parseable-types!
here's parseable-types approach working in example should work today:
using protobuf; using protobuf.meta; public class domaintypetobehandldedasstring { public string value { get; set; } public override string tostring() => value; public static domaintypetobehandldedasstring parse(string s) => new domaintypetobehandldedasstring { value = s }; } [protocontract] public class bar { [protomember(1)] public domaintypetobehandldedasstring { get; set; } } class program { static void main() { runtimetypemodel.default.allowparseabletypes = true; var obj = new bar { = new domaintypetobehandldedasstring { value = "abcdef" } }; var clone = serializer.deepclone(obj); system.console.writeline(clone.a.value); } }
Comments
Post a Comment