C#中仅含get的只读属性如何在类内赋值?底层机制是什么?
关于C#只读属性类内赋值的疑问解答
嗨~我来帮你把这个问题理清楚,你猜的方向其实是对的,但咱们可以把细节拆解得更明白一点:
首先,C#里“仅实现get的只读属性”的只读,指的是不能给属性本身重新赋值(比如不能写Series = new double[10];这种代码,类外肯定不行,类内如果没有私有set的话也不行),但如果属性的类型是引用类型(比如你提到的double[]数组),get访问器返回的是该引用类型对象的引用,这时候你就可以通过这个引用修改对象内部的内容。
举个贴合你场景的代码例子:
public class DataProcessor { // 私有字段存储数组 private double[] _series = new double[5]; // 仅暴露get的只读属性 public double[] Series { get { return _series; } // 没有public或private set,完全隐藏set逻辑 } public void FillData() { // 类内循环给数组元素赋值,完全合法 for (int i = 0; i < Series.Length; i++) { Series[i] = i * 2.0; } } }
这里的关键是:你不是在给Series属性本身赋值,而是通过Series返回的引用,直接操作背后的_series数组对象的元素——这就和C++里返回指针/引用,然后通过指针修改指向的内存内容是一个道理。
反过来,如果属性是值类型(比如int、DateTime这类),那get返回的是字段的副本,这时候别说类外,类内也没法通过属性修改原字段的值,比如:
public class Counter { private int _count; public int Count { get { return _count; } } public void TryIncrement() { // 这行代码会直接报错,因为没有set访问器,而且Count返回的是值副本 // Count++; } }
所以总结一下:你的猜测核心是正确的——因为get返回了引用类型的引用,所以你能修改引用指向的对象内部状态;但要注意,这和“给属性本身赋值”是完全不同的两件事,属性的“只读”限制的是前者,而非后者。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

