【发布时间】:2014-11-03 17:23:55
【问题描述】:
假设我有以下课程:
public class Test {
int x { get; set; }
int y { get; set; }
Vector3 coords { get; set; }
}
如果我不能在来自外部程序集的Vector3 类上使用[ProtoContract] 和[ProtoMember(x)] 属性,我该如何序列化这个对象。
我已阅读How can I serialize a 3rd party type using protobuf-net or other serializers?,但它含糊不清(例如,我不知道是否可以混合使用 TypeModel 和属性方法,或者如果我选择仅使用,如何将未知类型成员作为字段添加到已知类型成员TypeModel 方法等),所以我需要一个具体的例子来说明我的情况。
例如,我这样声明 TypeModel:
RuntimeTypeModel.Default.Add(typeof(Vector3), false).Add(1, "x").Add(2, "y").Add(3, "z");
RuntimeTypeModel.Default.Add(typeof(SerializableTestClass), false).Add(1, "_x").Add(2, "_y").Add(3, "_coords");
序列化/反序列化:
if (GUILayout.Button("Serialize")) {
SerializableTestClass testClass = new SerializableTestClass();
testClass.changeMembers();
RuntimeTypeModel.Default.Serialize(_serializedObject, testClass);
}
if (GUILayout.Button("Deserialize")) {
SerializableTestClass test = (SerializableTestClass) RuntimeTypeModel.Default.Deserialize(_serializedObject, null, typeof(SerializableTestClass));
Debug.Log("Deserialized object: " + test.ToString());
}
当我尝试序列化时,我得到一个错误:
InvalidOperationException: Duplicate field-number detected; 1 on: SerializableTestClass
更新 =============================
现在,我更改了我的代码,所以一切看起来像这样: 可序列化类:
[ProtoContract]
public class SerializableTestClass {
[ProtoMember(1)]
int _x { get; set; }
[ProtoMember(2)]
int _y { get; set; }
[ProtoMember(3)]
Vector3 _coords { get; set; }
public SerializableTestClass() {
Debug.Log("SerializableTestClass.ctor()");
_x = 10;
_y = 20;
_coords = Vector2.one * 2;
}
public void changeMembers() {
_x += -3;
_y += 134;
_coords *= 3;
}
public override string ToString() {
return _x.ToString() + " " + _y + " " + _coords;
}
}
型号:
_model = TypeModel.Create();
_model.Add(typeof(Vector3), false).Add(1, "x").Add(2, "y").Add(3, "z");
_model.Add(typeof(SerializableTestClass), true);
序列化/反序列化:
if (GUILayout.Button("Serialize")) {
SerializableTestClass testClass = new SerializableTestClass();
_serializedObject = new MemoryStream();
testClass.changeMembers();
_model.Serialize(_serializedObject, testClass);
}
if (GUILayout.Button("Deserialize")) {
SerializableTestClass test = (SerializableTestClass) _model.Deserialize(_serializedObject, null, typeof(SerializableTestClass));
Debug.Log("Deserialized object: " + test.ToString());
}
输出:10 20 (2.0, 2.0, 2.0)
应该是:7 154 (6.0, 6.0, 6.0)
【问题讨论】:
-
你读过这个article吗?我认为这对你来说是一个很好的例子。
-
@Rotem 我读过它,但我需要的是确切的例子,因为我不知道我应该只向模型添加未知类型,还是应该将所有内容添加到模型中并一起省略属性。文档并不清楚。我尝试了不同的方法,但它们似乎不起作用。
-
可以,可以混搭类型;所以你可以在
Test/SerializableTestClass上使用属性,并使用RuntimeTypeModel来配置Vector3。重新“重复字段编号”...您确定您只使用一次Add(每个字段)吗? -
@MarcGravell 是的,我确定。但是,我将它添加到 RuntimeTypeModel.Default。但是当我将类描述添加到通过 TypeModel.Create() 创建的类型模型时,序列化至少可以工作。不是我期望的那样,但至少它在调试中显示了一些东西。我在原始帖子中添加了更多说明。
标签: c# serialization protobuf-net