C# 为什么是{get;private set}列表';s的内容可以更改吗?

C# 为什么是{get;private set}列表';s的内容可以更改吗?,c#,C#,例如: class Foo { List<Object> myList {get;private set;} } 我知道这是允许的,但为什么?这背后的设计逻辑是什么?如果您可以从列表中添加/删除内容,那么它实际上不是一个私有集。列表对象不能更改,但其内容可以更改。比如,如果你去一家商店,它的目录夹在桌子上,你仍然可以从中添加/删除页面 如果需要类似的语义(以防止类的使用者修改列表),可以返回 class Foo { private List<Object>

例如:

class Foo {
  List<Object> myList {get;private set;}
}
我知道这是允许的,但为什么?这背后的设计逻辑是什么?如果您可以从列表中添加/删除内容,那么它实际上不是一个私有集。

列表对象不能更改,但其内容可以更改。比如,如果你去一家商店,它的目录夹在桌子上,你仍然可以从中添加/删除页面

如果需要类似的语义(以防止类的使用者修改
列表),可以返回

class Foo
{
    private List<Object> _myList;

    public IEnumerable<Object> MyEnumerable
    {
        get
        {
            return _myList;
        }
    }
}

如果
引用
类型允许读访问,则其
公共
方法也将公开
。重要的是要记住,
myList
的状态是可变的,但是对它的
引用
不能从外部更改。

无论何时从属性或方法返回对象,接收者都有对该对象的引用,并可以调用其属性或方法。如果该对象具有可设置的属性或方法更改其状态后,收件人可以修改对象(或者他们可以将对象传递给其他修改对象的对象)

设为set
私有
只意味着另一个类不能将属性设置为其他列表或null。但是,当另一个类获得对该列表的引用时,它可以调用
添加
清除
或任何其他方法

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

class Foo
{
    private List<Object> _myList;
    IReadOnlyList<Object> MyList => _myList.AsReadOnly();
    // or IReadOnlyCollection. 
    // Items in a IReadOnlyList are accessible by index.
}
class-Foo
{
私人名单;
IReadOnlyList MyList=>u MyList.AsReadOnly();
//或IReadOnlyCollection。
//IReadOnlyList中的项可以通过索引访问。
}
类内部有一个列表,但其他类只能访问列表中的只读项集合。它们不能修改集合


但是,通过返回对象列表,收件人确实可以访问这些对象中的每一个。它们不会以某种方式变成“只读”。如果它们具有可设置的属性或更改其内部状态的方法,则仍然可以对其进行修改。

私有集
表示您(在类之外)无法将myList设置为其他列表。这并不意味着myList指向的列表内容无法更改

这意味着你不能这样做

myFoo.myList = new List<Object>();

它是一个私有集,但不是私有get,因此您可以访问列表的Add方法,该方法是公共的。只要有一个公共getter,您就可以对getter返回的对象执行任何操作。但是,您不能设置
mylist
(例如
foo.mylist=new list()
).列表就像一个袋子,因为有私人设置,你不能更改袋子,但你可以使用袋子(填充、清空等)您可以拥有一个私有的
列表
,属性可以返回MSDN中建议的
只读集合
,这样一来,消费者就无法更改集合或内容您没有更改
myList
的值。您只需对其调用一个方法,该方法只调用
get
我不建议使用returning
IEnumerable
,因为它不允许通过索引进行随机访问。我建议将其作为
IReadOnlyList
返回,尽管消费者可以将其还原为正常的
IList
。我建议改为使用
ReadOnlyCollection
,因为它是最安全的。这是防止有人修改的唯一真正方法无论您返回哪个集合,都将创建一个新集合(或通过使属性
产生返回值
来创建迭代器)。不过,我同意您对
ReadOnlyCollection
的看法。我不会修改我的答案以包含您的建议,因为其他答案已经涵盖了这一点。
class Foo
{
    private List<Object> _myList;
    IReadOnlyList<Object> MyList => _myList.AsReadOnly();
    // or IReadOnlyCollection. 
    // Items in a IReadOnlyList are accessible by index.
}
myFoo.myList = new List<Object>();
myFoo.myList.Add(o);