[英]XmlSerializer.Deserialize doesn't work with the base class even with XmlInclude
[英]XmlSerializer.Deserialize() Does not appear to work
据我所知,我能够以 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 在方法中指向哪个;您可以更改其中的数据,但这是其他主题) 。 严格来说,“ object 是通过引用传递给方法的,而引用本身是通过值传递的;如果确实需要在方法中重新分配引用,请为此使用修饰符”。
所以要么使用 ref/out 修饰符(正如 BrettCaswell 在评论部分指出的那样,out 是首选;这是说“内容通过引用传递并将在内部重新分配”的方式,而 ref 表示“内容通过引用传递并且可能是重新分配内部”):
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 方法来解决解析数据和为解析提供状态的类似任务); 这是 integer(值类型)的示例: https://docs.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netframework-4.8
您可以使用泛型类型函数,它使您的代码可重用于其他 object 类型。 我无法检查我的代码,所以它可能会出现一些错误。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.