C#字典值求和异常:累加后仅获NULL值的问题排查与解决
年度数据累加后字典值为NULL的问题排查与解决
我需要对年度数据进行求和计算,代码按日执行,计算完成后累加每日结果以得到年度值,最终导出至SQL。目前已完成数据表配置并成功导出每日数据,但年度数据处理存在问题:代码中optResultYear的各属性已有正确计算值,但将其累加至Dictionary<float, OptResultYear>类型的yearlyResults字典后,字典中的对应值却为NULL。相关代码如下:
// YEAR OVERVIEW OptResultDataYear optResultDataYear = new OptResultDataYear(); // Variations in price List<float> varprijs = new List<float> { 0.06f, 0.08f, 0.10f, 0.12f, 0.14f, 0.16f, 0.18f }; // Create dictionaries for storing the values Dictionary<float, OptResultYear> yearlyResults = varPrijs.ToDictionary(co => co, co => new OptResultYear { AfdelingId = afd.AfdelingsId, variatiePrijs = co }); // SQL output OptResultYear optResultYear= new OptResultYear(); for (DateTime date = startYear; date < endYear; date = date.AddDays(1)) { foreach (float co in varprijs) { // Calculate the optimal results with the varPrijs ResultScenDay optResultvar = await DayCalc.RunOcapOptimaalDayAsync(afd.AfdelingsId, date, 3600, (int)ScenarioType.Optimal, co, null); // per dag met uurdata. // Analyze the code optResultYear = analysePeriode.FillOptResultYear(afd.AfdelingsId, kenm.TeeltOppHa, date, optResultvar, co, null); // Collect the required values yearlyResults[co].OptTotalDos += (float)optResultYear.OptTotalDos; yearlyResults[co].OptDos1 += (float)optResultYear.OptDos1; yearlyResults[co].OptDos2 += (float)optResultYear.OptDos2; yearlyResults[co].OptCost += (float)optResultYear.OptCost; yearlyResults[co].OptProductie += (float)optResultYear.OptProductie; yearlyResultsCO2[co].OptConcLp += (float)optResultYear.OptConcLp; // Set the date for the last entry yearlyResultsCO2[co].Datum = date; } }
问题原因
- 变量命名不一致:定义的价格列表变量是
varprijs(全小写),但创建yearlyResults字典时使用的是varPrijs(首字母P大写),如果这是两个不同的变量,会导致字典初始化错误,后续累加时无法找到正确的键,返回NULL。 yearlyResultsCO2未初始化:代码中直接对yearlyResultsCO2[co]进行赋值,但未看到该字典的初始化代码,若未提前为每个co创建OptResultYear实例,访问时会返回NULL,导致数据无法正确累加。- 浮点数键的精度问题:使用
float作为字典键,由于浮点数的精度特性,可能出现逻辑相等的浮点数实际哈希值不同的情况,导致累加时无法匹配到正确的字典条目,最终得到NULL。
解决方法
修正变量命名,确保字典初始化正确
将字典创建代码中的varPrijs改为varprijs,保证使用的是同一个价格列表变量:Dictionary<float, OptResultYear> yearlyResults = varprijs.ToDictionary(co => co, co => new OptResultYear { AfdelingId = afd.AfdelingsId, variatiePrijs = co });初始化
yearlyResultsCO2字典
在使用yearlyResultsCO2前,为每个价格变量创建对应的OptResultYear实例:Dictionary<float, OptResultYear> yearlyResultsCO2 = varprijs.ToDictionary(co => co, co => new OptResultYear { AfdelingId = afd.AfdelingsId, variatiePrijs = co });优化字典键类型(可选)
避免使用float作为字典键,可将其转换为整数(如乘以100转为整数)或改用decimal类型,减少精度损失:// 示例:转为整数键 Dictionary<int, OptResultYear> yearlyResults = varprijs.ToDictionary(co => (int)(co * 100), co => new OptResultYear { AfdelingId = afd.AfdelingsId, variatiePrijs = co });添加空值检查,避免异常
在累加前通过TryGetValue检查字典条目是否存在且非空,防止空引用异常:if (yearlyResults.TryGetValue(co, out var yearlyEntry) && yearlyEntry != null) { yearlyEntry.OptTotalDos += (float)optResultYear.OptTotalDos; yearlyEntry.OptDos1 += (float)optResultYear.OptDos1; yearlyEntry.OptDos2 += (float)optResultYear.OptDos2; yearlyEntry.OptCost += (float)optResultYear.OptCost; yearlyEntry.OptProductie += (float)optResultYear.OptProductie; } if (yearlyResultsCO2.TryGetValue(co, out var co2Entry) && co2Entry != null) { co2Entry.OptConcLp += (float)optResultYear.OptConcLp; co2Entry.Datum = date; }
内容的提问来源于stack exchange,提问作者Markje
相关产品推荐
相关产品推荐

