【问题标题】:Protobuf-Net Cannot Deserialize Record Without Parameterless ConstructorProtobuf-Net 无法在没有无参数构造函数的情况下反序列化记录
【发布时间】:2021-09-04 13:58:40
【问题描述】:

考虑以下代码示例;我希望能够使用 protobuf-net 序列化(工作正常)和反序列化(不起作用)Account 记录:

public abstract record State
{
    public abstract ISet<Identity> Identities { get; }

    public SerializedState Serialize()
    {
        using MemoryStream stream = new();
        Serializer.Serialize(stream, this);
        return new SerializedState(stream.ToArray(), GetType());
    }
}

public sealed record Account(Identity Owner, string Identifier, decimal Balance) : State
{
    public override ISet<Identity> Identities => new HashSet<Identity> {Owner};
}

ProtoBuf 合约配置有效:

RuntimeTypeModel
    .Default
    .Add<Account>()
    .Add(nameof(Account.Owner))
    .Add(nameof(Account.Identifier))
    .Add(nameof(Account.Balance));

但我得到以下异常:

ProtoBuf.ProtoException:没有为 Example.Account 找到无参数构造函数

有没有办法配置反序列化(不使用属性)以允许没有无参数构造函数的记录?

【问题讨论】:

标签: c# deserialization protocol-buffers protobuf-net


【解决方案1】:

记录的属性默认为init-only,因此实际上可以通过 反射设置。因此,您的Account 记录可以由 反序列化,方法是绕过this answer 中解释的构造函数,由Marc GravellDoes protobuf-net support C# 9 positional record types?

由于您是在运行时为Account 初始化合约,因此请修改您的初始化代码以设置MetaType.UseConstructor = false,如下所示:

var accountMeta = RuntimeTypeModel
    .Default
    .Add<Account>()
    .Add(nameof(Account.Owner))
    .Add(nameof(Account.Identifier))
    .Add(nameof(Account.Balance));          
accountMeta.UseConstructor = false;

现在你可以这样做了:

var account = new Account(identity, "Foo", 1.1m);       
var state = account.Serialize();
var account2 = (Account)Serializer.NonGeneric.Deserialize(state.Type, new MemoryStream(state.Data));

我假设SerializedState 看起来像这样:

public class SerializedState
{
    public SerializedState(byte [] data, Type type) => (Data, Type) = (data, type);
    
    public byte [] Data { get; set; }
    public System.Type Type { get; set; }
}

演示小提琴here.

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-04-11
  • 1970-01-01
  • 2013-09-07
  • 2010-10-10
  • 2015-12-23
  • 2021-12-16
  • 2018-06-28
相关资源
最近更新 更多