代码:- (注意:- 这里我使用只读词表示属性只有 get 访问器。
Class Test
{
public List<string> list {get;}
public string name{get;}
public Test ()
{
list =new List<string>();
}
}
Main()
{
Test test =new Test();
test.list.add("c#"); //no error
test.name="Jhon"; //here I get compilation because property name is read-only
}
如果您看到上面的代码段。测试类包含两个属性,即名称和列表。在 main 方法中,我正在创建测试类的对象来访问这些属性。因此,如果您看到我是否尝试将值设置为名称属性,那么我会收到编译错误,因为名称属性是只读的。同样,如果您看到另一个属性"list",如果我使用 List 类的添加属性,它也是只读的,那么我可以毫无错误地添加到列表中。 所以我不明白这是怎么发生的。
这是因为set
是指设置List
对象,即集合的实际实例。返回时,List
本身不是只读的。如果您希望它是只读的,您可以执行以下操作:
private List<string> list;
public ReadOnlyCollection<string> List {get => list.AsReadOnly()}
您对"只读"属性的工作方式有误解。
如果您的代码如下所示:
Test test = new Test();
test.list.Add("c#"); //no error because you are not 'setting' the object
test.list = new List<string>(); //Error here because you ARE setting the object
Add()
只是List<T>
的方法,您正在修改对象而不是将属性设置为其他内容。
如果您希望您的集合是"只读"的,您可以使用ReadOnlyCollection
界面。 您可以在内部管理private
列表,并且仅通过public ReadOnlyCollection
公开。 您想要的功能从未明确过,因此我不知道除了我所拥有的之外该建议什么。
这是因为在string
的情况下,您返回实例的副本 - 您无法分配给它。
为什么 .NET 字符串是不可变的?
如果是List<T>
,则返回对实例的引用,这在您的情况下不是恒定的 - 可以更改它。
为了证明自己,你可以做这样的事情:
class Test
{
private string val;
public ref string Val {get {return ref val;}}
}
void Main()
{
Test t = new Test();
t.Val = "a";
Console.WriteLine("t.Val is - " + t.Val);
}
观察我在string
属性中使用的特殊ref
关键字,以表示必须返回string
引用而不是它的副本。
C# 概念:值与引用类型(Joseph Albahari(
public List<string> list {get;}
这意味着,如果您使用name
执行相同的操作,则会导致错误。
test.list = new List<string>();
test.list
获取list
对象,并调用list
对象的 Add 方法。所以这很正常。