XmlSerializer.Deserialize()似乎不起作用

问题描述 投票:0回答:2

据我所知,我能够成功地序列化并以XML UTF-8格式保存数据,但是我无法反序列化非常相同的数据。

我已经尝试研究此问题,但是似乎没有人遇到反序列化不起作用的相同问题。至少我认为这就是问题所在。

    public static class XMLManager
    {
        //Save Function
        public static void SaveItemsUTF(ItemDatabase itemDB)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ItemDatabase));
            string filename = Application.dataPath + "/StreamingFiles/XML/item_data.xml";
            Encoding encoding = Encoding.GetEncoding("UTF-8");

            using (StreamWriter stream = new StreamWriter(filename, false, encoding))
            {
                serializer.Serialize(stream, itemDB);
            }
        }

        //Load Function
        public static void LoadItems(ItemDatabase itemDB)
        {
            //Open an XML File
            if (File.Exists(Application.dataPath + "/StreamingFiles/XML/item_data.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(ItemDatabase));
                FileStream stream = new FileStream(Application.dataPath + "/StreamingFiles/XML/item_data.xml", FileMode.Open);
                itemDB = serializer.Deserialize(stream) as ItemDatabase;
                stream.Close();
            }
            else
            {
                Debug.LogError("File not found!");
            }
        }

        //Delete Function
        public static void DeleteItems()
        {
            //Delete an XML File
            File.Delete(Application.dataPath + "/StreamingFiles/XML/item_data.xml");
        }
    }

    [System.Serializable]
    public class ItemEntry
    {
        public string ItemName;
        public SaveMaterial material;
        public int Value;
    }

    [System.Serializable]
    public class ItemDatabase
    {
        [XmlArray("CombatEquipment")]
        public List<ItemEntry> list = new List<ItemEntry>();
    }

    public enum SaveMaterial
    {
        Wood,
        Copper,
        Iron,
        Steel,
        Obsidian
    }

[当我使用SaveItemsUTF方法时,它会在正确的位置成功生成一个文件,其中包含正确格式的测试数据,可以在此处找到:https://imgur.com/a/5PJMTRh

但是,当我使用LoadItems方法时,什么也没发生。没有错误或在控制台中登录。没有数据被加载。它似乎无能为力。我正式被困。

c# xml unity3d
2个回答
2
投票

已反序列化。您可以放置​​断点,并查看LoadItems中的元素已填充正确的数据。

但是现在的问题是值/引用类型在.NET中的工作方式。 您不能在使用方法的地方更改值(重新分配引用,方法中itemDB指向该值;但是您可以在其中更改数据,但这是另一种拓扑)严格来说,“ 对象是通过引用传递给方法的,但是引用本身是通过值传递的;如果确实需要在方法中重新分配引用,请对该参数使用修饰符”]

所以要么使用ref / out修饰符(如BrettCaswell在评论部分所指出,首选out;这是说“内容通过引用传递,will在内部重新分配”的方式,而ref表示“ content is通过引用传递并且might在内部重新分配“):

public static void LoadItems(out ItemDatabase itemDB); // will work; but you'll call it as below, with out modifier: 
// XMLManager.LoadItems(out itemDBName);

或更改为:

public static ItemDatabase LoadItems(); // also will work, but, of course, you'll need to  create ItemDatabase internally in LoadItems

。NET封装了TryParse方法,以解决解析数据和提供解析状态的相似任务);这是整数(值类型)的示例:https://docs.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netframework-4.8


1
投票

您可以使用通用类型函数,它使您的代码可重用于其他对象类型。我无法检查我的代码,因此它可能会给出一些错误。

static void Serialize<T>(T data, string path)
{
    FileStream fs = new FileStream(path, FileMode.Create);
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    serializer.Serialize(fs, data);
    fs.Close();
}


static T Deserialize<T>(string path)
{
    FileStream fs = new FileStream(path, FileMode.Open);
    XmlSerializer xs = new XmlSerializer(typeof(T));
    T obj = (T)xs.Deserialize(fs);
    fs.Close();
    return obj;
}
© www.soinside.com 2019 - 2024. All rights reserved.