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

C#中传递对象至其他方法后,为何无法通过Get/Set属性访问值?

C#对象参数传递中Get属性访问问题解答

原因分析

你遇到的栈溢出错误,核心原因是**Account类的属性实现存在无限递归逻辑**。通常是定义属性的get/set方法时,错误地直接返回或赋值属性本身,而非对应的私有字段。例如:

// 错误示例:无限递归触发栈溢出
public double AccAmount {
    get { return AccAmount; } // 每次调用get都会重复触发自身,形成无限循环
    set { AccAmount = value; }
}

即使直接访问_accAmount字段仍出现溢出,大概率是该字段与属性的逻辑绑定错误,或是构造函数中错误使用属性赋值导致递归。

需要明确的是:对象作为参数传递给方法后,完全可以通过Get属性获取值,这是C#的基础用法,你的问题与参数传递无关,仅和类的属性实现有关。

解决方案

正确实现类的属性,严格区分私有字段与公开属性,两种可行方式如下:

方式1:使用自动属性(推荐)

C#支持自动属性,编译器会自动生成对应的私有字段,无需手动维护:

public class Account
{
    // 自动属性,编译器自动处理底层私有字段
    public int AccNo { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public double AccAmount { get; set; }
    public int MobileNumber { get; set; }
    public string Location { get; set; }
    public bool IsActive { get; set; }

    // 构造函数
    public Account(int accNo, string firstName, string lastName, double accAmount, int mobileNumber, string location, bool isActive)
    {
        AccNo = accNo;
        FirstName = firstName;
        LastName = lastName;
        AccAmount = accAmount;
        MobileNumber = mobileNumber;
        Location = location;
        IsActive = isActive;
    }

    // 保留现有索引器逻辑
    public object this[int index]
    {
        get
        {
            return index switch
            {
                0 => AccNo,
                1 => FirstName,
                2 => LastName,
                3 => MobileNumber,
                4 => AccAmount,
                5 => Location,
                _ => throw new IndexOutOfRangeException("Invalid index")
            };
        }
    }
}

方式2:手动实现属性(含自定义逻辑)

若需要在get/set中添加校验或其他自定义逻辑,可显式绑定私有字段:

public class Account
{
    // 私有字段,以下划线开头区分属性
    private int _accNo;
    private string _firstName;
    private string _lastName;
    private double _accAmount;
    private int _mobileNumber;
    private string _location;
    private bool _isActive;

    // 公开属性,帕斯卡命名法
    public int AccNo
    {
        get => _accNo;
        set => _accNo = value;
    }

    public double AccAmount
    {
        get => _accAmount;
        set
        {
            // 添加金额非负校验
            if (value < 0)
                throw new ArgumentException("Account amount cannot be negative");
            _accAmount = value;
        }
    }

    // 其他属性按相同逻辑实现
    public string FirstName
    {
        get => _firstName;
        set => _firstName = value ?? throw new ArgumentNullException(nameof(value));
    }

    // 构造函数和索引器同上
}

修改后的调用示例

在CheckBalance方法中,直接通过属性访问即可正常获取值:

public static void CheckBalance(Account a)
{
    Console.WriteLine(a.AccAmount); // 无栈溢出,正常输出金额
    Console.WriteLine(a[0]); // 保留索引器用法不受影响
}

额外规范建议

  • 遵循C#命名约定:私有字段用下划线前缀(如_accAmount),公开属性用帕斯卡命名(如AccAmount),避免命名混淆。
  • 优先使用自动属性减少冗余代码,仅在需要自定义逻辑时手动实现属性。

内容的提问来源于stack exchange,提问作者Ankita Roy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:37:28