gpt4 book ai didi

c# - 在 Protobuf-net 中序列化一个抽象列表

转载 作者:太空宇宙 更新时间:2023-11-03 13:35:58 25 4
gpt4 key购买 nike

我的应用程序中有以下类结构:

[ProtoContract]
public abstract class WebSyncedObject
{
[ProtoMember(1)]
public DateTime SystemTime { get; set; }

[ProtoMember(2)]
public bool TimeSynchronized { get; set; }

[ProtoMember(3)]
public ulong RelativeTime { get; set; }

[ProtoMember(4)]
public Guid BootID { get; set; }

protected WebSyncedObject()
{
BootID = BootID.GetBootID();
if (BootID == Guid.Empty) return;

TimeSynchronized = Time.TimeSynchronized;
RelativeTime = Time.RelativeTime;
SystemTime = DateTime.Now;
}
}

[ProtoContract]
public class GPSReading : WebSyncedObject
{
[ProtoMember(1)]
public DateTime SatelliteTime { get; set; }

[ProtoMember(2)]
public decimal Latitude { get; set; }

[ProtoMember(3)]
public decimal Longitude { get; set; }

[ProtoMember(4)]
public int NumSatellites { get; set; }

[ProtoMember(5)]
public decimal SpeedKM { get; set; }
}

[ProtoContract]
public class TemperatureReading : WebSyncedObject
{
[ProtoMember(1)]
public decimal Temperature { get; set; }

[ProtoMember(2)]
public int NodeID { get; set; }

[ProtoMember(3)]
public string ProbeIdentifier { get; set; }
}

然后我用两种类型的数据构造一个 List ,并在出现以下异常时尝试使用 Protobuf-net 进行序列化:

InvalidOperationException Unexpected sub-type: Logger.TemperatureReading

我已经阅读了有关 ProtoInclude 属性的信息,但我不想使用它,因为我的代码需要易于扩展,而且我不确定 RuntimeTypeModel 方法的编号应该如何工作,因为我还看到了关于自动生成它的警告。

有什么方法可以实现这一点,同时使其可扩展吗?

最佳答案

最终,需要有一种健壮、可靠和可重复的方法来让库识别具有唯一标识符(字段编号)的特定子类型(GPSReading 等)。在许多情况下,最方便的方法是通过属性。但是,如果这不是一个选项,您也可以在运行时执行此操作——也许读取某个配置文件的标识符。只是说(在运行时)“找到所有可用的子类型,按字母顺序排列,并从(比如)10 开始增加它们”并不是一个好主意,因为在以后的构建中你可能已经添加了一个 AltitudeReading,这将改变一切的数量,破坏现有数据。但只要您能以可重复的方式 定义这些,那么一切都很好。例如,具有属性...

[ProtoInclude(10, typeof(GPSReading))]
[ProtoInclude(11, typeof(TemperatureReading))]
[ProtoInclude(12, typeof(AltitudeReading))]

但是您也可以在文本文件或 xml 配置文件中做一些事情...也许:

<add key="10" type="Some.Namespace.GPSReading"/>
<add key="11" type="Some.Namespace.TemperatureReading"/>
<add key="12" type="Some.Namespace.AltitudeReading"/>

并添加您自己的代码来读取配置文件并调用:

int key = int.Parse(element.GetAttributeValue("key"));
Type type = someAssembly.GetType(element.GetAttributeValue("type"));
RuntimeTypeModel.Default[typeof(WebSyncedObject)].AddSubType(key, type);

再次强调:重要的是与每个子类型关联的数字必须在未来可靠地重复。只要你能保证,就不需要使用属性。但是模型确实需要知道标识符。

关于c# - 在 Protobuf-net 中序列化一个抽象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18695728/

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