gpt4 book ai didi

c# - 用于可选分配的可空类型(不是集合)的 Protobuf-net 模式

转载 作者:行者123 更新时间:2023-12-05 05:02:05 34 4
gpt4 key购买 nike

我已经搜索了一段时间,并找到了表明 protobuf-net 可以处理可空类型的各种线程,关于诸如空集合(此处不相关)之类的各种线程,以及以前的默认值行为一直是 proto2 中的“可选”字段,但我还没有找到以下问题的具体答案。这将是我第一次使用 protobuf-net 或 Protocol Buffer 作为序列化格式。

想象一下,我正在使用事件携带状态传输模式在多个不同的应用程序之间发送消息 - 因此消息的发布者和订阅者包含状态 - 以及该状态的某种共享模型。任何参与的应用程序都具有“相同”实体的某种表示(因此是 ECST),但并非所有系统都理解所有属性。就应用程序的 SQL 数据库中的持久性而言,它可能看起来像这样(为简洁起见省略了比例):

table App1Products { productKey int, productName varchar null }

table App2Products { productKey int, productName varchar null, productWeightKg decimal null }

table App3Products { productKey int }

为了示例,假设简单的共享模型是所有不同属性的联合:{ productKey, productName, productWeightKg }

现在假设有人在 App1Products 中更新了一个 productName。我们想要发布更改后的状态。当我们这样做时,我们无法填充整个共享模型,因为 App1 在其架构中不包含 productWeightKg。我们需要以某种方式“遗漏”此元素的任何值,让潜在消费者明白它未被填充。

我们不能仅发送默认值 (0)(或让订阅者将缺失的元素反序列化为默认值)来传达“无更新”语义,因为那样会导致 productWeightKg 值当 App2 收到消息时,在 App2Products 表中设置为 0。我们不能发送 null 来传达“无更新”语义,因为 null 也是该列的合法值。

最终,我们需要 App2 的订户代码构造一个更新语句,以便不引用 productWeightKg 列,或者将其简单地设置为自身,我们需要某种方式告诉 App2 的订阅者代码来做到这一点。

一个解决方案似乎是在消息中为每个字段创建一个附加元素,指示该字段是否已设置。在消息内容方面,我们可能会使用这样的东西:

[ProtoContract]
public class Product
{
[ProtoMember(1)]
public int ProductKey { get; set; }

[ProtoMember(2)]
public string productName { get; set; }

[ProtoMember(3)]
public decimal? productWeightKg { get; private set; }

[ProtoMember(4)]
public bool productWeightKgSet { get; private set; }

public void SetProductWeight(decimal? weight)
{
productWeightKg = weight;
productWeightKgSet = true;
}

public void ClearProductWeight()
{
productWeightKgSet = false;
}
}

如果这是一种合理的模式,那么下一个“显而易见”的想法就是为这种行为创建某种模板类,我们可以将其重用于我们所有的消息类......

public class Optional<T>
{
public T Value { get; private set; }
public bool HasValue { get; private set; }

public void Set(T val) { Value = val; HasValue = true; }
public void Clear() { HasValue = false; Value = default; }
}

这是解决此问题的一种合理方法,还是我错过了其他一些“已知的好模式”,或者这种模式不能像预期的那样与 protobuf-net 一起工作?

我目前有限的理解是,这可能需要使用 ProtoInclude 属性使用其所有可能的子实现来装饰 Optional 类,对吗?

最佳答案

最终,protobuf-net 的目的不是提供一个强大的字段跟踪机制,并且由于它针对 POCO 类型工作 - 它没有地方可以存储任何额外的状态,除了你的对象模型提供。它确实支持considitonal序列化,您的模型可以做很多事情来跟踪内部变化,如讨论的here ;这可能与 Merge 结合使用(而不是反序列化)——但超越它并不是开箱即用的东西(大多数其他 POCO 序列化器也没有提供,据我所知)。

您描述的内容与 FieldMask 之间有一些交叉概念,但是:到目前为止,protobuf-net 还没有实现或支持 FieldMask 的需要。

我总是乐于探索图书馆可能能够帮助人们的新事物,但如果缺少图书馆功能:这可能是在 GitHub 上讨论得更好的东西,以及目标的非常具体的细节场景和动机等

关于c# - 用于可选分配的可空类型(不是集合)的 Protobuf-net 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62397017/

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