我想在我的游戏引擎中使用 protobuf-net,我遇到了这个任务——我如何有效地区分存储和运行时类型?
基本上,数据在磁盘上的存储方式与运行时加载的格式不同。
简化示例:我使用类似这样的类将一些 GPU 相关数据序列化为字节 []:
[ProtoContract(UseProtoMembersOnly=true)]
public sealed class StoredData
{
[ProtoMember(1)]
public byte[] GpuData;
}
然后我会有这个类的运行时实现,我会在其中将该字节缓冲区上传到显卡,因此会有完全不同的类型,类似于“class GraphicsBuffer”而不是“byte[]”。
此外,在序列化运行时类型“GraphicsBuffer”时,我也想序列化完全不同的消息 - 例如磁盘上的路径或要反序列化的 StoredData 的名称。
这一切归结为:
我如何交换用于序列化的类型,同时能够定义回调以在这些类型之间进行转换?这样(例如)
1.当我序列化SoredData时,一个StoredData被写入
2.当我反序列化GraphicsBuffer时,StoredData被反序列化并转换为GraphicsBuffer
3.当我序列化 GraphicsBuffer 时,该缓冲区的“缓冲区路径消息”被序列化
4.当我反序列化'buffer path message'时,'buffer path message'被反序列化,然后找到StoredData并使用该消息反序列化,而StoredData的反序列化产生从StoredData中的信息创建的GraphicsBuffer。
我希望这是有道理的!
最佳答案
我认为所有这些问题的答案都是“代理人”。例如:
// needs to be done once only, before any serialization/deserialization is done
RuntimeTypeModel.Default.Add(typeof(GraphicsBuffer), false)
.SetSurrogate(typeof(StoredData));
与:
[ProtoContract(UseProtoMembersOnly= true)]
public sealed class StoredData
{
[ProtoMember(1)]
public byte[] GpuData;
public static explicit operator GraphicsBuffer(StoredData value)
{
if (value == null) return null;
throw new NotImplementedException("Your conversion code here");
}
public static explicit operator StoredData(GraphicsBuffer value)
{
if (value == null) return null;
throw new NotImplementedException("Your conversion code here");
}
}
self 注意:我应该通过属性使这成为可能,这样您就不需要在运行时操作模型。
现在,每当模型遇到 GraphicsBuffer
时,它都会使用到/从 StoredData
的转换运算符,并在 StoredData 上运行序列化/反序列化代码
实例。
关于c# - Protobuf-net 交换类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21132161/