使用 protobuf-net 反序列化字典
Posted
技术标签:
【中文标题】使用 protobuf-net 反序列化字典【英文标题】:Deserialize Dictionary with protobuf-net 【发布时间】:2015-03-12 12:34:16 【问题描述】:由于 BinaryFormatter 给我在 ios 上序列化字典带来了麻烦,我决定切换到 protobuf-net。并使用它来序列化我的 Unity3d 游戏中的内容。这是一些代码: 这是保存所有数据的类:
using System;
using System.Collections.Generic;
using ProtoBuf;
using UnityEngine;
namespace SerializationLib
[ProtoContract]
public class GameData
[ProtoMember(1)]
public int _coinAmount ;
[ProtoMember(2)]
public int _upgradeLevel;
[ProtoMember(3)]
public Level_Data[] _level_Data;
[ProtoMember(4)]
public CharacterUpgradeList _charUpgradeList;
[ProtoMember(5)]
public SerialVector2 serialVector;
[ProtoContract]
public class CharacterUpgradeList
private List<UpgradeData>[] upgData;
[ProtoMember(1,OverwriteList = true)]
public Dictionary<string, List<UpgradeData>> upgradeList;
public CharacterUpgradeList()
upgData = new List<UpgradeData>[4];
for (int i = 0; i < upgData.Length; i++)
upgData[i] = new List<UpgradeData>
new UpgradeData(),
new UpgradeData(),
new UpgradeData(),
new UpgradeData(),
new UpgradeData(),
new UpgradeData()
;
upgradeList = new Dictionary<string, List<UpgradeData>>
"Man",upgData[0],
"Woman",upgData[1],
"Boy",upgData[2],
"Girl",upgData[3]
;
[ProtoContract]
public class Level_Data
[ProtoMember(1)]
public int completion_status;
[ProtoMember(2)]
public int star_Rating;
[ProtoContract]
public class UpgradeData
[ProtoMember(1)]
public bool lockStatus;
[ProtoMember(2)]
public bool purchased;
[ProtoContract]
public struct SerialVector2
[ProtoMember(1)]
public float x;
[ProtoMember(2)]
public float y;
public SerialVector2(Vector2 vect)
x = vect.x;
y = vect.y;
public Vector2 returnVector2()
return new Vector2(x, y);
这是我正在使用的数据序列化器
using System;
using System.Collections.Generic;
using SerializationLib;
using ProtoBuf.Meta;
namespace DataSerializer
class Program
static void Main(string[] args)
var Model = TypeModel.Create();
Model.Add(typeof(GameData), true);
Model.Add(typeof(CharacterUpgradeList), true);
Model.Add(typeof(Level_Data), true);
Model.Add(typeof(UpgradeData), true);
Model.Add(typeof(SerialVector2), true);
Model.AllowParseableTypes = true;
Model.AutoAddMissingTypes = true;
Model.Compile("DataSerializer", "DataSerializer.dll");
这是一个 protobuf 包装器,可在我的其他 c# 脚本中统一使用
using UnityEngine;
using System.IO;
public static class ProtoWraper
private static DataSerializer m_serialiezer = new DataSerializer();
public static T LoadObjectFromResources<T>(string resourcePath)
TextAsset objectAsset = Resources.Load(resourcePath, typeof(TextAsset)) as TextAsset;
if (objectAsset == null)
return default(T);
T deserializedObject = default(T);
using (MemoryStream m = new MemoryStream(objectAsset.bytes))
deserializedObject = (T)m_serialiezer.Deserialize(m, null, typeof(T));
return deserializedObject;
public static T LoadObjectFromPath<T>(string path)
if (!File.Exists(path))
return default(T);
T deserializedObject = default(T);
using(FileStream f = new FileStream(path,FileMode.Open))
deserializedObject = (T)m_serialiezer.Deserialize(f,null,typeof(T));
return deserializedObject;
public static void SaveObjectToPath<T>(string objectPath, string filename, T serializedObject)
if (!Directory.Exists(objectPath))
Directory.CreateDirectory(objectPath);
using (FileStream f = new FileStream(objectPath + filename, FileMode.OpenOrCreate))
m_serialiezer.Serialize(f, serializedObject);
现在的问题是当我打电话给data = ProtoWraper.LoadObjectFromPath<GameData>(filename);
我得到ArgumentException: An element with the same key already exists in the dictionary.
【问题讨论】:
【参考方案1】:没关系,我是个彻头彻尾的白痴,在更改 Serializationlib 后没有重新编译数据序列化程序:D。现在一切都好。
【讨论】:
以上是关于使用 protobuf-net 反序列化字典的主要内容,如果未能解决你的问题,请参考以下文章
我可以使用 protobuf-net 在 Mono 中序列化一个对象(包含成员:字典、列表...等)并在 MS.NET 中反序列化它,反之亦然?