为什么{get; private set}列表的内容可以更改?

时间:2018-01-17 23:51:16

标签: c#

例如:

class Foo {
  List<Object> myList {get;private set;}
}

然后在其他脚本中,我仍然可以这样做

foo.myList.Add(new Object());

我知道这只是允许但是为什么?这背后的设计逻辑是什么?如果您可以在列表中添加/删除内容,那么它实际上不是私有集。

4 个答案:

答案 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。但是当另一个类获得对该列表的引用时,它可以调用AddClear或任何其他方法。

如果您想保护列表中的内容,可以执行以下操作:

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);