据我所知,我能够成功地序列化并以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方法时,什么也没发生。没有错误或在控制台中登录。没有数据被加载。它似乎无能为力。我正式被困。
已反序列化。您可以放置断点,并查看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
您可以使用通用类型函数,它使您的代码可重用于其他对象类型。我无法检查我的代码,因此它可能会给出一些错误。
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;
}