Protobuf.net 列表的对象图序列化

2024-02-03

据我了解,protobuf.net 的列表不支持 AsReference,因此我尝试解决此限制。我创建了一个名为 SuperList 的自定义列表,其中包含包装在 SuperListItem 类型的对象中的项目,如下所示:

[ProtoContract]
public class SuperList<T> where T : class
{
    [ProtoMember(1)]
    private List<SuperListItem<T>> _items = new List<SuperListItem<T>>();

    public SuperList()
    {
    }

    public int IndexOf(T item)
    {
        int indexOf = -1;
        for (int index = 0; index < _items.Count; index++)
        {
            if (_items[index].Item == item)
            {
                indexOf = index;
                break;
            }
        }
        return indexOf;
    }

    public void Insert(int index, T item)
    {
        _items.Insert(index, new SuperListItem<T>(item));
    }

    public void RemoveAt(int index)
    {
        _items.RemoveAt(index);
    }

    public T this[int index]
    {
        get
        {
            return _items[index].Item;
        }
        set
        {
            _items[index] = new SuperListItem<T>(value);
        }
    }

    public void Add(T item)
    {
        _items.Add(new SuperListItem<T>(item));
    }

    public void Clear()
    {
        _items.Clear();
    }

    public bool Contains(T item)
    {
        bool contains = false;
        foreach (var listItem in _items)
        {
            if (listItem.Item == item)
            {
                contains = true;
                break;
            }
        }
        return contains;
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        for (int index = arrayIndex; index < _items.Count; index++)
            array[index] = _items[index].Item;
    }

    public int Count
    {
        get { return _items.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(T item)
    {
        SuperListItem<T> itemToRemove = null;
        foreach (var listItem in _items)
        {
            if (listItem.Item == item)
            {
                itemToRemove = listItem;
                break;
            }
        }
        if (itemToRemove != null)
            _items.Remove(itemToRemove);

        return itemToRemove != null;
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach(var listItem in _items)
            yield return listItem.Item;
    }
}

[ProtoContract]
public class SuperListItem<T>
{
    [ProtoMember(1, AsReference = true)]
    private readonly T _item;
    public T Item { get { return _item; } }

    private SuperListItem() { }

    public SuperListItem(T item)
    {
        _item = item;
    }
}

我有以下序列化测试代码:

[ProtoContract]
public class Thing
{
    [ProtoMember(1)]
    private readonly string _name;
    public string Name { get { return _name; } }

    private Thing() { }

    public Thing(string name)
    {
        _name = name;
    }
}

public class ProtoTest3
{
    public void Serialize()
    {
        SuperList<Thing> list = GetListOfThings();

        using (var fs = File.Create(@"c:\temp\things.bin"))
        {
            ProtoBuf.Serializer.Serialize(fs, list);

            fs.Close();
        }

        using (var fs = File.OpenRead(@"c:\temp\things.bin"))
        {
            list = ProtoBuf.Serializer.Deserialize<SuperList<Thing>>(fs);

            Debug.Assert(list[0] == list[2]);

            fs.Close();
        }
    }

    private SuperList<Thing> GetListOfThings()
    {
        var thing1 = new Thing("thing1");
        var thing2 = new Thing("thing2");

        var list = new SuperList<Thing>();
        list.Add(thing1);
        list.Add(thing2);
        list.Add(thing1);

        return list;
    }
}

但是,当我运行代码时,出现异常“没有为此对象定义无参数构造函数”。这只是 ProtoBuf.Net 的限制,还是我做错了什么?有办法解决这个问题吗?


澄清;列表的限制很简单列表本身不被视为参考。这items are,只要它们位于标记的成员上AsReference- 例如:

    [Test]
    public void SerializeTheEasyWay()
    {
        var list = GetListOfThings();

        using (var fs = File.Create(@"things.bin"))
        {
            ProtoBuf.Serializer.Serialize(fs, list);

            fs.Close();
        }

        using (var fs = File.OpenRead(@"things.bin"))
        {
            list = ProtoBuf.Serializer.Deserialize<MyDto>(fs);

            Assert.AreEqual(3, list.Things.Count);
            Assert.AreNotSame(list.Things[0], list.Things[1]);
            Assert.AreSame(list.Things[0], list.Things[2]);

            fs.Close();
        }
    }

    [ProtoContract]
    public class MyDto
    {
        [ProtoMember(1, AsReference = true)]
        public List<Thing> Things { get; set; }
    }

    private MyDto GetListOfThings()
    {
        var thing1 = new Thing("thing1");
        var thing2 = new Thing("thing2");

        var list = new List<Thing>();
        list.Add(thing1);
        list.Add(thing2);
        list.Add(thing1);

        return new MyDto {Things = list};
    }

(有趣的事实 - 这实际上是exactly电线上也一样)

There does然而,在这种情况下,它创建实例的方式似乎是一个错误;它正在使用.ctor和失败。我将调查并解决这个问题,但是以下方法也有效:

1: 使参数无参数.ctor public:

        public Thing()
        {
        }

2:或者,禁用.ctor:

    [ProtoContract(SkipConstructor = true)]
    public class Thing
    { ...

我将调查为什么私有无参数构造函数在这种情况下不满意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Protobuf.net 列表的对象图序列化 的相关文章

随机推荐

  • 是否有类似于 XMLSpy 的带有网格视图的 XML 编辑器? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我已经测试了一些不同的 xml 编辑器 查看器 但似乎找不到任何具有与 XMLSpy 的网格视图相媲美的
  • 使用 Rails 3 输出格式化的 json

    我使用rails 3 0 3 javascript 自动完成需要这样的数据 query Li suggestions Liberia Libyan Arab Jamahiriya Liechtenstein Lithuania data L
  • Golang 嵌入结构类型

    我有这些类型 type Value interface type NamedValue struct Name string Value Value type ErrorValue struct NamedValue Error error
  • Kotlin 如何与 Java 和 JavaScript 互操作?

    Kotlin 网站指出 Kotlin 与 Java 100 具有互操作性 Kotlin 是 Java 的子集 超集吗 另外 文档指出 Kotlin 与 JavaScript 兼容 那么它是如何编译以支持两者的呢 Kotlin 是像 Xama
  • 内循环 Lambda

    我在 for 循环中有一个 lambda 其中循环变量参数在 lambda 中 当我运行它时 我期望输出数字 0 9 但由于它是 lambda 因此 x 不会立即求值 for int x 0 x lt n x vec push back t
  • 如何解决java.io.InvalidClassException:本地类不兼容:流classdesc serialVersionUID [重复]

    这个问题在这里已经有答案了 我在这么大的项目中有一个可序列化的类 编码时没有指定serialVersionUID 并将其作为blob保存在MySQL数据库中 我必须向此类添加一些字段 但是执行此操作后 我收到如下异常 IOException
  • 文本装饰:下划线与边框底部

    使用上有什么区别 text decoration underline and border bottom 哪个易于设计且跨浏览器兼容 当我们应该使用border bottom over text decoration underline 用
  • 使用 Lua 表 C API 创建一个简单的表

    我正在运行一个 MySQL 查询 它总是返回 4 行 row gt name row gt date row gt ip row gt custom 我想要实现的是根据上述结果创建一个简单的表 因此它看起来像 name result of
  • 如何将信号作为函数参数传递?

    因此 我希望创建我们自己的通用继承复选框类 该类将能够在其构造函数中接受一些值 并弹出一个以我们需要的方式完全连接到我们的模型的小部件 目前我们在我们的视野范围内做这样的事情 connect checkboxWidget QCheckbox
  • 如何在android中使用intent发送.text文件?

    我正在使用下面的代码发送邮件 并且我需要仅使用 gmail 发送 text 文件 我该怎么做 请问有人可以帮助我吗 Intent send new Intent Intent ACTION SENDTO String uriText mai
  • 需要为 Yesod 路径定义哪些类型类?

    在我的应用程序中 我的数据模型有几个使用整数或字符串作为某些标识符的不同实例 为了安全起见 我将这些标识符包装到新类型声明中 如下所示 newtype DocId DocId Integer newtype GroupName GroupN
  • 在 Pixel 2 和 Pixel 2 XL 上接收 UDP 广播数据包

    我正在开发一个从 Wi Fi 摄像头接收 UDP 广播数据包的应用程序 在我发现 Google Pixel 2 Pixel 2 XL 接收 UDP 广播包有问题之前一直都很好 为了找出原因 我做了2个测试应用程序 一个是UPD广播发送器 h
  • Python - 作业 - 将任意基数转换为任意基数

    我正在尝试编写一个程序 将任何基数中的数字转换为用户选择的另一个基数 到目前为止我的代码是这样的 innitvar float raw input Please enter a number basevar int raw input Pl
  • Facebook 登录后调用新活动 |安卓

    我的 Android 应用程序中有 2 个活动 在第一个中 我要求用户使用 facebook 登录 用户登录后 我收集用户数据 例如电子邮件 姓名 并调用一个新活动 将这些参数传递给它 下面是我的facebook授权方法 public vo
  • PlopJS 中的异步操作

    我想在 actions 属性中使用 async await 但是 它给了我 错误 处理程序没有任何操作 我尝试过 then 但仍然失败了 这是我到目前为止所尝试过的 我想做的是通过在操作中执行反应式提示 我不知道 然后使用await但失败了
  • 两种方式将数据绑定到单例服务 Blazor 服务器端

    我一直在使用 WebAssembly 在客户端上使用 Blazor 但我想我现在应该尝试服务器端版本 并且我有一个简单的想法想要尝试 所以我的理解是 Blazor 服务器端使用 SignalR 来 推送 更改 以便客户端重新渲染其页面的一部
  • 如何在javascript中从对象数组中获取唯一的对象

    我有一系列对象 如下图所示 有没有一种方法可以让我拥有一个包含唯一对象的数组id 我们可以在下面看到id索引 0 和索引 2 相同 Is there a way that I can get an array containing obje
  • 在不同架构的集群上应该指定哪个AVX和march?

    我目前正在尝试使用英特尔编译器编译用于 HPC 集群的软件 登录节点是我编译和准备计算的地方英特尔至强金牌 6148 https ark intel com content www us en ark products 120489 int
  • 从 PHP 执行 wkhtmltopdf

    我在 Linux 命令行下运行得很好 wkhtmltopdf 入口 html 输出 pdf 但以下内容在 PHP 代码中不起作用 exec wkhtmltopdf入口 html输出 pdf 有趣的是 我用谷歌搜索了很多未经检查的解决方案 但
  • Protobuf.net 列表的对象图序列化

    据我了解 protobuf net 的列表不支持 AsReference 因此我尝试解决此限制 我创建了一个名为 SuperList 的自定义列表 其中包含包装在 SuperListItem 类型的对象中的项目 如下所示 ProtoCont