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

C#银行系统SortedSet未按余额降序排列及构造函数添加实例疑问

问题解决与优化方案

一、排序异常的原因及修复

你的代码中SortedSet未按余额降序输出,核心问题有两个:

1. 比较逻辑方向错误

当前CompareTo方法使用return _balance.CompareTo(other._balance),这是升序逻辑(余额小的对象会排在前面)。要实现降序,必须反转比较方向:

public int CompareTo(Bank? other)
{
    if (other == null) return 1; // 空对象后置
    // 余额相同则按ID升序保证唯一性,避免SortedSet去重错误
    if (_balance == other._balance) return _id.CompareTo(other._id);
    // 反转比较方向实现余额降序
    return other._balance.CompareTo(_balance);
}

2. 构造函数添加时机错误

带余额参数的构造函数先调用无参构造(此时_balance为默认值0),将未完成初始化的对象添加到SortedSet,之后才设置实际余额。这导致集合排序基于初始的0值而非最终余额。修复方式是先初始化余额,再添加到集合:

public Bank()
{
    _id = numOfAccounts;
    numOfAccounts++;
    // 移除构造函数内的_banks.Add(this)
}

public Bank(double balance) : this()
{
    _balance = balance;
    _banks.Add(this); // 先设置余额再加入集合
}

另外,withdrawal方法修改余额后未更新集合排序,需要补充Remove/Add操作:

public bool withdrawal(double balance)
{
    if(this._balance >= balance) { 
        _banks.Remove(this);
        this._balance -= balance;
        _banks.Add(this);
        return true;
    }
    return false;
}

二、构造函数中添加实例的合理性分析

这种做法存在明显缺陷:

  • 强耦合:创建Bank对象就必须加入静态集合,无法灵活创建独立的账户实例(比如测试用例)。
  • 初始化风险:构造函数执行时对象可能未完全初始化(如之前的余额设置滞后问题),导致集合中存储的对象状态不一致。
  • 扩展性差:后续如果需要多个账户集合(比如按不同维度分类),现有逻辑无法支持。

三、更优实现方案

1. 分离集合管理与账户逻辑

将静态集合的管理从Bank类中剥离,创建单独的BankManager类负责维护账户集合,让Bank类专注于账户自身逻辑:

public class BankManager
{
    private readonly SortedSet<Bank> _accounts = new SortedSet<Bank>(new BankComperatorByBalance());

    public void AddAccount(Bank account)
    {
        _accounts.Add(account);
    }

    public bool RemoveAccount(Bank account)
    {
        return _accounts.Remove(account);
    }

    public IEnumerable<Bank> GetAccountsSortedByBalanceDesc()
    {
        return _accounts;
    }
}

public class Bank : IComparable<Bank>
{
    private static int numOfAccounts = 0;
    public int Id { get; }
    public double Balance { get; private set; }

    public Bank(double balance)
    {
        Id = numOfAccounts++;
        Balance = balance;
    }

    public void Deposit(double amount)
    {
        Balance += amount;
    }

    public bool Withdraw(double amount)
    {
        if (Balance >= amount)
        {
            Balance -= amount;
            return true;
        }
        return false;
    }

    public bool Transfer(Bank receiver, double amount)
    {
        if (Withdraw(amount))
        {
            receiver.Deposit(amount);
            return true;
        }
        return false;
    }

    public override string ToString()
    {
        return $"id: {Id}\nBalance: {Balance}";
    }

    public int CompareTo(Bank? other)
    {
        if (other == null) return 1;
        if (Balance == other.Balance) return Id.CompareTo(other.Id);
        return other.Balance.CompareTo(Balance);
    }

    public override bool Equals(object? obj)
    {
        return obj is Bank bank && Id == bank.Id;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

class BankComperatorByBalance : Comparer<Bank>
{
    public override int Compare(Bank? x, Bank? y)
    {
        if (x == null) return 1;
        if (y == null) return -1;
        return x.CompareTo(y);
    }
}

2. 使用静态创建方法(简化版)

如果不想新增类,可以用静态方法封装对象创建与集合添加逻辑,同时将构造函数设为私有避免直接实例化:

public class Bank : IComparable<Bank>
{
    private static int numOfAccounts = 0;
    private readonly int _id;
    private double _balance;
    private static readonly SortedSet<Bank> _banks = new SortedSet<Bank>(new BankComperatorByBalance());

    // 私有构造函数,强制通过静态方法创建
    private Bank(double balance)
    {
        _id = numOfAccounts++;
        _balance = balance;
    }

    public static Bank CreateAccount(double balance)
    {
        var account = new Bank(balance);
        _banks.Add(account);
        return account;
    }

    // 存款、取款等方法按修复后的逻辑实现
}

3. 修正Transfer方法逻辑

原代码中transfer方法逻辑错误(转出方误用了存款操作),正确实现如下:

public bool Transfer(Bank receiver, double balance)
{
    if (this._balance >= balance)
    {
        this.withdrawal(balance);
        receiver.deposit(balance);
        return true;
    }
    return false;
}

内容的提问来源于stack exchange,提问作者Adam Hafchadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:12:04