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
相关产品推荐
相关产品推荐

