You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中Linq GroupBy调用Sum方法时出现类型转换报错

问题根因

这个报错和Sum本身的求和逻辑无关,是两个问题导致的:

  1. 你将匿名类型生成的强类型集合声明为IEnumerable<dynamic>,后续所有LINQ操作都会丢失编译期类型检查,调用Sum()时动态绑定逻辑错误匹配了返回int的重载,最终尝试把decimal类型的求和结果隐式转换为int时触发类型不匹配错误。
  2. 计算hist_angsuran的三目分支存在逻辑错误:Decimal.Parse(line.Substring(141, 13) + 1)中,Substring返回的是字符串,和整数1做+运算会直接执行字符串拼接,相当于在截取的13位字符串末尾多拼接一个"1"再转decimal,完全不符合「解析后数值加1」的预期。
修复方案
  • 移除类级别的private IEnumerable<dynamic> histix声明,在方法内直接用var接收文件解析生成的集合,让编译器自动推断匿名类型的强类型,从根源上避免动态绑定的重载匹配错误。
  • 修正hist_angsuran的计算逻辑,把+1的数值运算放到Decimal.Parse()括号外部,避免字符串拼接。
  • Sum方法不需要做任何int类型转换,类型修正后编译器会自动匹配decimal版本的Sum重载,直接返回decimal类型的求和结果,完全不会出现数值超出int范围的问题。
  • 建议把Sum lambda的参数名和外层Select的参数名做区分,避免同名导致的可读性下降。

修复后的完整代码如下:

public void CreateADKTran()
{
    // 用var接收,自动推断为强类型匿名集合
    var histix = File.ReadLines(PATH_LNHISTIX)
                    .Skip(1)
                    .Where(line => line.Substring(157, 3) == "PKK" &&
                                    Decimal.Parse(line.Substring(141, 16)) != 0 &&
                                    line.Substring(80, 1) != "*" &&
                                    (line.Substring(58, 1) == "6" || line.Substring(58, 3) == "310"))
                    .Select(line => new
                    {
                        hist_acct_no = line.Substring(0, 10),
                        hist_tran_date = DateTime.ParseExact(line.Substring(61, 8), "yyyyMMdd", provider),
                        hist_outstanding = Decimal.Parse(line.Substring(89, 13)),
                        // 修正+1位置,在数值层面做加法
                        hist_angsuran = (Decimal.Parse(line.Substring(102, 2)) + Decimal.Parse(line.Substring(154, 2))) >= 100 ?
                                                            Decimal.Parse(line.Substring(141, 13)) + 1 : Decimal.Parse(line.Substring(141, 13)),
                        hist_txn_code = line.Substring(58, 3),
                        hist_txn_type = line.Substring(58, 1)
                    });

    var histixSum = histix.GroupBy(x => new { x.hist_acct_no, x.hist_tran_date, x.hist_txn_type })
                                    .Select(x => new {
                                        histAcctno = x.Key.hist_acct_no,
                                        histTranDate = x.Key.hist_tran_date,
                                        histTxnType = x.Key.hist_txn_type,
                                        histOS = x.Last().hist_outstanding,
                                        // Sum自动识别decimal类型,直接返回decimal结果
                                        histAngsuran = x.Sum(item => item.hist_angsuran),
                                        histTxnCode = x.Last().hist_txn_code
                                    });
}

注:原代码中多处Substring()后额外调用ToString()属于冗余写法,Substring()本身返回值就是字符串类型,可以直接使用。

内容的提问来源于stack exchange,提问作者Anthony Pangestu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 19:06:22