C#使用XDocument将变量保存为XML及程序重启后加载数据的问题
XML始终存储0值的核心原因
代码执行顺序存在逻辑错位:
- 进入月份判断分支后,第一时间就基于初始值为0的
fixcosts、costs两个变量创建XDocument对象,此时XML节点绑定的就是两个0值 - 后续才执行用户输入、数值累加的逻辑,已经实例化完成的XDocument对象内容不会自动同步后续修改的变量值,最终执行
Save方法时,写入文件的自然还是最初的0值 - 另外当前代码直接把数值和" Euro"字符串拼接存在节点值里,后续程序重启要读取数据时,需要额外拆分字符串、提取数字,不仅操作麻烦,还容易出现解析错误
可实现持久化+重启加载的完整方案
- 调整XML创建时机:等所有变量完成计算、拿到最终需要持久化的数值后,再实例化XDocument对象,避免提前固化旧的变量值
- 优化XML存储结构:将数值和单位拆分存储,数值节点存纯数字方便后续解析,单位作为XML属性单独存储,不混在节点内容里
- 补充启动加载逻辑:程序运行时先判断目标XML文件是否存在,如果存在就读取节点值赋值回对应变量;如果不存在再给变量设置默认初始值0,实现程序重启后自动恢复历史数据
修正后的参考代码
double fixcosts = 0.0; double costs = 0.0; Maths math = new Maths(); int month = DateTime.Today.Month; // 定义固定的文件存储路径 string savePath = @"C:\Users\tobia\Desktop\Neuer Ordner\fixcosts_january.xml"; if (month == 1) { // 程序启动时优先加载历史保存的数据 if (File.Exists(savePath)) { var savedDoc = XDocument.Load(savePath); // 读取节点纯数值赋值回变量 fixcosts = Convert.ToDouble(savedDoc.Descendants("Fixcosts").First().Value); costs = Convert.ToDouble(savedDoc.Descendants("Costs").First().Value); } // 打印当前已加载的数值 Console.WriteLine("\n JANUARY COSTS \n"); Console.WriteLine($"Fixcosts = {fixcosts}"); Console.WriteLine($"Costs = {costs}"); // 处理用户输入,计算新的数值 Console.WriteLine("\n\nHow much you wanna add?"); double howMuch = Convert.ToDouble(Console.ReadLine()); fixcosts = math.Addieren(fixcosts, howMuch); Console.Clear(); Console.WriteLine("\n JANUARY COSTS \n"); Console.WriteLine($"Fixcosts = {fixcosts}"); Console.WriteLine($"Costs = {costs}"); // 所有变量值计算完成后,再创建XML对象 XDocument January_costs_categories = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XElement("CostsCategories", new XAttribute("CurrencyUnit", "Euro"), // 单位单独作为属性存储 new XElement("Fixcosts", fixcosts), new XElement("Costs", costs) )); // 执行保存操作 January_costs_categories.Save(savePath); }
落地注意事项
- 避免直接将程序数据存在桌面目录:普通权限运行程序时,可能因为系统权限限制无法写入桌面文件,建议换成系统提供的AppData专属存储路径,减少IO报错概率
- 增加解析异常处理:读取XML节点转数值时,增加格式校验逻辑,避免XML被手动修改为非数字内容时直接引发程序崩溃
内容的提问来源于stack exchange,提问作者Krunki
相关产品推荐
相关产品推荐

