Protobuf-Net NotSupportedException:类型不能表示为已关闭的不可变类型的默认值(UnityEngine.Vector3)

时间:2018-06-01 09:02:07

标签: c# unity3d serialization protocol-buffers protobuf-net

根据How to serialize a closed immutable type with protobuf-netProtobuf-net and Unity3D types的答案,我尝试了一个可以处理UnityEngine的Vector3容器的序列化程序,其中唯一重要的值是Vector3.x,Vector3.y和Vector3。 Z:

使用以下TypeModel:

serializer = TypeModel.Create();
serializer.UseImplicitZeroDefaults = false;

然后我尝试了两种不同的方法,分别为Vector3添加协议定义;一个明确的定义:

serializer.Add(typeof(Vector3), false).Add(1, "x").Add(2, "y").Add(3, "z");

使用代理人:

serializer.Add(typeof(Vector3), false).SetSurrogate(typeof(SurrogateVector3));

使用代理类:

[ProtoContract]
public sealed class SurrogateVector3
{
    [ProtoMember(1)]
    float x; 
    [ProtoMember(2)]
    float y; 
    [ProtoMember(3)]
    float z;

    public SurrogateVector3()
    {}

    public SurrogateVector3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public static implicit operator Vector3(SurrogateVector3 v)
    {
        return new Vector3(v.x, v.y, v.z);
    }

    public static implicit operator SurrogateVector3(Vector3 v)
    {
        return new SurrogateVector3(v.x, v.y, v.z);
    }
}

使用任一方法尝试序列化Dictionary<int, Vector3>时,会抛出以下异常:

NotSupportedException: Type cannot be represented as a default value: UnityEngine.Vector3
ProtoBuf.Serializers.DefaultValueDecorator.EmitBranchIfDefaultValue (ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.CodeLabel label) (at <5e93d5bf6f2048709aab19aea88deb74>:0)
...

我不确定如何修改我的Typemodel或协议定义,以便成功序列化UnityEngine.Vector3的集合。

1 个答案:

答案 0 :(得分:4)

这可能是&#34;地图&#34;中的一个错误。代码,需要修复。你现在可以通过添加:

来避免它
[ProtoMap(DisableMap = true)]

到属性/字段,即字典。 &#34;地图&#34;之间的区别代码和原始的预先&#34;地图&#34;代码是微妙的,不是很有趣 - 它主要改变了重复的情况 - 但是:它似乎是&#34; map&#34;中的一个烦人的错误。逻辑,可能并不存在于原始代码路径中。然而,&#34;地图&#34; path现在是默认值,因此禁用它的解决方法。