gpt4 book ai didi

protobuf-net - 如何使用 protobuf-net 序列化封闭的不可变类型?

转载 作者:行者123 更新时间:2023-12-05 01:07:32 27 4
gpt4 key购买 nike

比如我想序列化和反序列化System.Drawing.Font这是不可变的,不能更改以适应 protobuf-net 约定。一般来说,是否可以在 protobuf-net 中编写某种“自定义”序列化程序?

编辑 :根据接受的答案,这里是 System.Drawing 的代理示例:

[ProtoContract]
struct ProtoColor
{
[ProtoMember(1, DataFormat=DataFormat.FixedSize)]
public uint argb;
public static implicit operator Color(ProtoColor c)
{ return Color.FromArgb((int)c.argb); }
public static implicit operator ProtoColor(Color c)
{ return new ProtoColor { argb = (uint)c.ToArgb() }; }
}
[ProtoContract()]
class ProtoFont
{
[ProtoMember(1)]
string FontFamily;
[ProtoMember(2)]
float SizeInPoints;
[ProtoMember(3)]
FontStyle Style;

public static implicit operator Font(ProtoFont f) {
return new Font(f.FontFamily, f.SizeInPoints, f.Style);
}
public static implicit operator ProtoFont(Font f) {
return f == null ? null : new ProtoFont {
FontFamily = f.FontFamily.Name,
SizeInPoints = f.SizeInPoints,
Style = f.Style };
}
}
[ProtoContract()]
class ProtoStringFormat
{
[ProtoMember(1, DataFormat=DataFormat.Group)]
StringAlignment Alignment;
[ProtoMember(2)]
StringAlignment LineAlignment;
[ProtoMember(3)]
StringFormatFlags Flags;
public static implicit operator StringFormat(ProtoStringFormat f) {
return new StringFormat(f.Flags) { Alignment = f.Alignment,
LineAlignment = f.LineAlignment };
}
public static implicit operator ProtoStringFormat(StringFormat f) {
return f == null ? null : new ProtoStringFormat() {
Flags = f.FormatFlags, Alignment = f.Alignment,
LineAlignment = f.LineAlignment };
}
}

// Before serializing or deserializing...
static RuntimeTypeModel Model;
static StaticConstructor()
{
Model = TypeModel.Create();
Model.AllowParseableTypes=true;
Model.Add(typeof(Color), false).SetSurrogate(typeof(ProtoColor));
Model.Add(typeof(Font), false).SetSurrogate(typeof(ProtoFont));
Model.Add(typeof(StringFormat), false)
.SetSurrogate(typeof(ProtoStringFormat));
Model.Add(typeof(PointF), true).Add("X", "Y");
}

最佳答案

是的。请注意,许多不可变类型将由“自动元组”代码处理 - 如果它有一个接受看起来像公共(public)成员的参数的构造函数,它可以从中推断出行为。

除此之外,您可以编写自己的 DTO,它具有您需要的任何布局/成员,并在自定义 DTO 和目标类型(在本例中为字体)之间添加转换运算符(隐式或显式)。您的运算符(operator)将拥有从一个到另一个的代码。然后调用:

 RuntimeTypeModel.Default.Add(typeof(Font), false)
.SetSurrogate(typeof(YourCustomDTO));

序列化器将使用运算符在两种类型之间进行切换,并使用在线上的自定义 DTO。

注意运算符的传入值是否为空!

关于protobuf-net - 如何使用 protobuf-net 序列化封闭的不可变类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18405160/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com