例如:
class Foo {
List<Object> myList {get;private set;}
}
然后在其他脚本中,我仍然可以这样做
foo.myList.Add(new Object());
我知道这只是允许但是为什么?这背后的设计逻辑是什么?如果您可以在列表中添加/删除内容,那么它实际上不是私有集。
答案 0 :(得分:1)
List<T>
对象无法更改,但其内容可以更改。就像你去商店并将其目录夹在桌面上一样 - 你仍然可以添加/删除页面。
如果您想要类似的语义(为了防止您的班级消费者修改List<T>
,您可以返回IEnumerable<T>
,而不是像这样
class Foo
{
private List<Object> _myList;
public IEnumerable<Object> MyEnumerable
{
get
{
return _myList;
}
}
}
如果您想使用MyEnumerable
,可以从中创建一个集合(例如调用ToList()
):
List<object> list = foo.MyEnumerable.ToList();
答案 1 :(得分:1)
每当从属性或方法返回对象时,收件人都会引用该对象,并可以调用其属性或方法。如果该对象具有可更改其状态的可设置属性或方法,则收件人可以修改该对象。 (或者他们可以将对象传递给修改它的其他东西。)
制作set
private
只是意味着另一个类无法将属性设置为其他列表或为null。但是当另一个类获得对该列表的引用时,它可以调用Add
,Clear
或任何其他方法。
如果您想保护列表中的内容,可以执行以下操作:
class Foo
{
private List<Object> _myList;
IReadOnlyList<Object> MyList => _myList.AsReadOnly();
// or IReadOnlyCollection.
// Items in a IReadOnlyList are accessible by index.
}
在内部,类有一个列表,但其他类只能访问列表中只读的项集合。他们无法修改集合。
但是,通过返回对象列表,收件人可以访问每个对象。他们不会以某种方式成为“只读”。&#34;如果它们具有可更改其内部状态的可设置属性或方法,则仍可以对其进行修改。
答案 2 :(得分:0)
如果reference
类型允许读取访问,则也会公开其public
方法。在这种情况下,.Add()
。重要的是要记住myList
的状态是可变的,但它的reference
不能在外部更改。
答案 3 :(得分:0)
private set
表示您(在课堂外)无法将myList设置为其他列表。它并不意味着myList指向的列表内容无法更改
即你这意味着你不能这样做
myFoo.myList = new List<Object>();
但是(正如你发现的那样)你可以做到这一点
myFoo.myList.Add(o);