实现Balance属性的get方法后,为何无法在构造函数中初始化该字段?
问题描述
在跟随MSDN教程学习时,为Balance属性实现get方法后,在构造函数中初始化该字段时出现以下错误:
error CS0200: Unable to assign value to property or indexer "BankAccount.Balance" - it is read only
我知道这是因为该属性没有set方法,但同样没有set方法的Number字段却能正常初始化,这是为什么?
相关代码
public class BankAccount{ private static int accountNumberSeed = 1234567890; public string Number {get;} public string Owner {get; set;} public decimal Balance{ get{ decimal balance = 0; foreach (var item in allTransactions){ balance += item.Amount; } return balance; } } public BankAccount(string name, decimal initialBalance){ this.Owner = name; this.Balance = initialBalance; this.Number = accountNumberSeed.ToString(); ++accountNumberSeed; } private List<Transaction> allTransactions = new List<Transaction>(); public void MakeDeposit(decimal amount, DateTime date, string note){ if (amount <= 0){ throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive"); } var deposit = new Transaction(amount, date, note); allTransactions.Add(deposit); } public void MakeWithdrawal(decimal amount, DateTime date, string note){ } }
原因解析
这两种属性的本质完全不同:
Number {get;}是自动实现的只读属性,C#编译器会自动为它生成一个私有的只读后备字段,并且语法规则允许在构造函数中直接给这类属性赋值。Balance是自定义getter的计算属性,它没有对应的后备字段,每次访问Balance时,都是通过遍历allTransactions集合计算出结果返回。这种属性本质上是一个返回值的方法包装,不存在可被赋值的字段,所以哪怕在构造函数里也无法直接赋值。
解决方法
要初始化Balance,你需要调用MakeDeposit方法将初始金额添加到交易列表中,这样Balance的getter计算时就能得到正确的初始值:
修改后的构造函数代码:
public BankAccount(string name, decimal initialBalance){ this.Owner = name; // 替换直接赋值Balance的代码,调用存款方法初始化 MakeDeposit(initialBalance, DateTime.Now, "初始存款"); this.Number = accountNumberSeed.ToString(); ++accountNumberSeed; }
内容的提问来源于stack exchange,提问作者user15799491
相关产品推荐
相关产品推荐

