我正在试图弄清楚我是如何成功更改“只读”数组的。下面的代码运行成功,但我很困惑为什么私有/只读数组的解除引用是合法的,如下所示:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Time[5] = 5; // Why is this legal? How can I make it illegal?
}
}
public class MyClass
{
private readonly uint[] time;
public IList<uint> Time
{
get { return time; }
}
public MyClass()
{
time = new uint[7];
}
}
}
正如我在上面提到的,由于公共IList Time没有设置器,我希望Time [5]是非法的。
如何更改MyClass以确保执行myClass.Time[5]
合法?
注意:我已经澄清了这个问题的意图,我一开始并不清楚是否打算制作这个ILLEGAL。我想先了解为什么它的合法性。
答案 0 :(得分:5)
如上所述,我希望如此 由于时间[5]是非法的 公共IList时间没有 有一个二传手。
缺少setter意味着您无法将NEW ARRAY分配给属性的支持字段,但这并不意味着您无法更改支持字段指向的CURRENT数组引用。
此外,我该如何创建 构造函数中的数组是 只读和不可改变的外部 这堂课?
您可以按照MSDN在声明阶段或类的构造函数中设置只读字段。
至于如何解决这个问题,以下MSDN article讨论了这个确切的问题以及解决问题的方法。我不确定您的要求是什么,但我建议您尝试使用ReadOnlyCollectionBase实现自定义集合,然后传递它,或者您可以使用ReadOnlyCollection<T>
。 ReadOnlyCollectionBase的链接提供了一个实现示例。
答案 1 :(得分:2)
readonly
表示字段本身无法更改(也就是说,你不能在构造函数之外说“this.time = new uint [10]”。数组是可变对象,因此无论您在何处引用数组,该引用的拥有者都可以更改存储在该数组中的值。
readonly
字段只能在构造函数中写入(这包括字段初始值设定项)
有两种选择:
答案 2 :(得分:0)
时间属性没有设置,所以你将无法做到这样的事情:
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Time = new List<uint>();
}
但您可以使用索引器,因此Time [5]是合法的。
此外,如何在构造函数中创建一个只读且在此类之外不可更改的数组?
只读字段只能在构造函数中初始化。声明后的初始化与构造函数中的初始化相同。