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

C#列表存储收支数据不丢失及最值展示异常问题咨询

解决C#收支管理程序列表数据丢失的问题

嘿,这个问题我之前帮好几个开发者踩过坑,十有八九是列表的作用域搞错了——你大概率是把Income和Outgo列表声明在了某个方法内部(比如菜单处理方法或者添加数据的方法里),每次执行那个方法时都会新建一个空列表,之前存的数据自然就被覆盖丢失了!

核心解决方案:把列表提升到类级别作用域

你需要把收入和支出列表声明为类的成员变量,而不是方法内的局部变量,这样它们的生命周期会和程序的菜单循环一致,每次添加数据都是往同一个列表里追加,不会被重置。

完整示例代码

using System;
using System.Collections.Generic;
using System.Linq;

class ExpenseManager
{
    // 把列表声明为类的私有成员,确保整个类的方法都能访问同一个实例
    private List<decimal> _incomeList = new List<decimal>();
    private List<decimal> _outgoList = new List<decimal>();

    static void Main(string[] args)
    {
        var manager = new ExpenseManager();
        manager.RunMenuLoop();
    }

    public void RunMenuLoop()
    {
        bool isRunning = true;
        while (isRunning)
        {
            Console.WriteLine("\n=== 收支管理菜单 ===");
            Console.WriteLine("1. 添加新收入");
            Console.WriteLine("2. 添加新支出");
            Console.WriteLine("3. 查看当前列表最值");
            Console.WriteLine("4. 退出");
            Console.Write("请选择操作:");
            
            var input = Console.ReadLine();
            switch (input)
            {
                case "1":
                    AddIncome();
                    break;
                case "2":
                    AddOutgo();
                    break;
                case "3":
                    ShowMinMaxValues();
                    break;
                case "4":
                    isRunning = false;
                    Console.WriteLine("程序已退出");
                    break;
                default:
                    Console.WriteLine("无效选项,请重新选择");
                    break;
            }
        }
    }

    private void AddIncome()
    {
        Console.Write("请输入收入金额:");
        if (decimal.TryParse(Console.ReadLine(), out decimal income))
        {
            _incomeList.Add(income);
            Console.WriteLine($"成功添加收入:{income:C}");
        }
        else
        {
            Console.WriteLine("输入格式错误,请输入有效的数字");
        }
    }

    private void AddOutgo()
    {
        Console.Write("请输入支出金额:");
        if (decimal.TryParse(Console.ReadLine(), out decimal outgo))
        {
            _outgoList.Add(outgo);
            Console.WriteLine($"成功添加支出:{outgo:C}");
        }
        else
        {
            Console.WriteLine("输入格式错误,请输入有效的数字");
        }
    }

    private void ShowMinMaxValues()
    {
        Console.WriteLine("\n=== 当前收支最值 ===");
        
        // 处理空列表的情况,避免调用Max/Min时抛出异常
        if (_incomeList.Any())
        {
            Console.WriteLine($"收入最大值:{_incomeList.Max():C}");
            Console.WriteLine($"收入最小值:{_incomeList.Min():C}");
        }
        else
        {
            Console.WriteLine("暂无收入数据");
        }

        if (_outgoList.Any())
        {
            Console.WriteLine($"支出最大值:{_outgoList.Max():C}");
            Console.WriteLine($"支出最小值:{_outgoList.Min():C}");
        }
        else
        {
            Console.WriteLine("暂无支出数据");
        }
    }
}

关键要点说明

  • 作用域问题:类级别的列表_incomeList和_outgoList会在ExpenseManager实例创建后一直存在,所有方法操作的都是同一个列表实例,不会出现数据丢失。
  • 空列表处理:调用Max()或Min()前先用Any()判断列表是否有数据,避免抛出InvalidOperationException异常。
  • 输入验证:用decimal.TryParse确保用户输入的是有效的金额,避免程序崩溃。

其他可能的排查方向

如果上面的方案解决不了你的问题,可以检查这几点:

  • 有没有在某个方法里不小心调用了_incomeList.Clear()或_outgoList.Clear()?
  • 是不是在传递列表时用了ToList()创建了副本,导致修改的是副本而不是原列表?
  • 有没有多线程操作列表的情况?(不过你的程序应该是单线程控制台程序,这个概率很低)

内容的提问来源于stack exchange,提问作者Amilto Romagno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:05:24