用protobuf-net反序列化字典

时间:2015-03-12 12:34:17

标签: c# ios dictionary unity3d protobuf-net

由于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 个答案:

答案 0 :(得分:1)

没关系,我是一个完整的白痴,并且在更改Serializationlib之后没有重新编译数据序列化器:D。现在一切都很好。