"预计不会输入类型,也不能推断合同:Leap.Vector"错误。使用Protobuf-net序列化程序

时间:2017-07-18 09:55:02

标签: c# serialization vector deserialization protobuf-net

我正在开发使用跳跃运动设备并使用C#实现的应用程序,我的问题是我想在我的数据库中存储包含Vectors的列表。所以我考虑过将向量转换为浮点数组的解决方案,问题是每个列表包含最多和最少300个值(将数据存储到数据库中需要一段时间)。

所以我搜索了其他可能的存储方式,最后我讨论了.net序列化的主题。我曾尝试实现内置的.net序列化。认为它有效,但仍然需要大约一分钟的序列化列表。因此,针对该主题提出的另一个解决方案是使用protobuf-net。所以我尝试使用nuget软件包安装程序安装它。并最终使用此功能(从解决方案Fastest way to serialize and deserialize .NET objects中复制)

public static byte[] Serialize(List<Vector> tData)
{
    using (var ms = new MemoryStream())
    {
        ProtoBuf.Serializer.Serialize(ms, tData);
        return ms.ToArray();
    }
}

public static List<Vector> Deserialize(byte[] tData)
{
    using (var ms = new MemoryStream(tData))
    {
        return ProtoBuf.Serializer.Deserialize<List<Vector>>(ms);
    }
}

但运行代码会导致我出现上述错误(标题)。

我认为错误发生在:ProtoBuf.Serializer.Serialize(ms, tData);

1 个答案:

答案 0 :(得分:0)

@dbc已经链接到类似代码re Point3D,但我想知道这里是否需要任何序列化器。这看起来很简单,只做原始(注意我假设float是这里的基础数据类型;如果没有,只需将所有sizeof(float)float*更改为正确的类型):

static unsafe byte[] Serialize(List<Vector> vectors)
{
    var arr = new byte[3 * sizeof(float) * vectors.Count];
    fixed(byte* ptr = arr)
    {
        var typed = (float*)ptr;
        foreach(var vec in vectors)
        {
            *typed++ = vec.X;
            *typed++ = vec.Y;
            *typed++ = vec.Z;
        }
    }
    return arr;
}
static unsafe List<Vector> Deserialize(byte[] arr)
{
    int count = arr.Length / (3 * sizeof(float));
    var vectors = new List<Vector>(count);
    fixed (byte* ptr = arr)
    {
        var typed = (float*)ptr;
        for(int i = 0; i < count; i++)
        {
            var x = *typed++;
            var y = *typed++;
            var z = *typed++;
            vectors.Add(new Vector(x, y, z));
        }            
    }
    return vectors;
}

如果您非常勇敢,您还可以尝试直接转储基础数据 ,而不是手动复制字段;如果sizeof(Vector)正好是3 * sizeof(float)(或任何基础类型),那么值得一试。