C# MessagePack MsgPack007 Cannot find a public constructor

2025-01-11  乐帮网

c# .net

在.net的项目中用到了MessagePack,挺香的,在使用过程中遇到错误MsgPack007 Cannot find a public constructor。代码编写如下:

[MessagePackObject(AllowPrivate =true)]
 public partial class Station
 {
     [Key(0)]
     private Person _manager;

     [Key(1)]
     private DateTime _buildDate;

     [Key(2)]
     public string Address { get; set; } = string.Empty;

     [Key(3)]
     public DateTime BuildDate => _buildDate;

     [Key(4)]
     public Person Manager => _manager;

     public Station(DateTime buildDate, Person manager)
     {
         _buildDate = buildDate;
         _manager = manager;
     }

 }
 
 
    [MessagePackObject]
    public record BaseObject() { [Key(0)] public int Type { get; set; }}

    [MessagePackObject]
    public record Person() : BaseObject
    {

        [Key(1)]
        public string UserName;
        [Key(2)]
        public int Age;
    }

 

 说是Station没有找到公用构造函数。在网上搜索发现属性标签 SerializationConstructor 可以指定序列化的构造函数。 官方给了一个使用示例如下:

[MessagePackObject]
public struct Point
{
    [Key(0)]
    public readonly int X;
    [Key(1)]
    public readonly int Y;

    [SerializationConstructor]
    public Point(int x)
    {
        this.X = x;
        this.Y = -1;
    }

    // If not marked attribute, used this(most matched argument)
    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

说的也清楚,SerializationConstructor标签可以指定优化使用的序列化构造函数。不然的话默认使用最匹配的。也就是 具有 key值最多化的构造函数。回到正题,最上面那段代码如何 在构造函数上添加标签后人发现报了另一个错。如下:

[SerializationConstructor]
 public Station(DateTime buildDate, Person manager)
     {
         _buildDate = buildDate;
         _manager = manager;
     }

报错:MsgPack007:Deserializing constructor parameter type mismatch
     显然这种解决方法行不对,我们的MessagePack还没有这么智能。这时我做了一个小小的改动就可以解决,把Station改成如下:

 [MessagePackObject(AllowPrivate =true)]
 public partial class Station
 {
     [Key(0)]
     private Person _manager;

     [Key(1)]
     private DateTime _buildDate;

     [Key(2)]
     public string Address { get; set; } = string.Empty;

     [Key(3)]
     public DateTime BuildDate => _buildDate;

     [Key(4)]
     public Person Manager => _manager;

     public Station() { }

     public Station(DateTime buildDate, Person manager)
     {
         _buildDate = buildDate;
         _manager = manager;
     }

 }

发现问题解决了。使用一切正常,等等== 即使我们加了一个默认构造函数,这个破坏了代码设计初衷,于是灵机一动改成如下:

 [MessagePackObject(AllowPrivate =true)]
 public partial class Station
 {
     [Key(0)]
     private Person _manager;

     [Key(1)]
     private DateTime _buildDate;

     [Key(2)]
     public string Address { get; set; } = string.Empty;

     [Key(3)]
     public DateTime BuildDate => _buildDate;

     [Key(4)]
     public Person Manager => _manager;

     private Station() { }

     public Station(DateTime buildDate, Person manager)
     {
         _buildDate = buildDate;
         _manager = manager;
     }

 }

 一切都工作的很好,外面又恢复了灿烂的阳光。项目地址:

https://github.com/MessagePack-CSharp/MessagePack-CSharp

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力