列出属性设置器

mik*_*igs 5 c# encapsulation list

当为List属性(在C#中)实现setter时,编写它是一件坏事:

    private List<string> _TheList = new List<string>();
    public List<string> TheList
    {
        get { return _TheList; }
        set { _TheList = value; }
    }
Run Code Online (Sandbox Code Playgroud)

它不应该写成:

    private List<string> _TheList = new List<string>();
    public List<string> TheList
    {
        get { return _TheList; }
        set { _TheList = new List<string>(value); }
    }
Run Code Online (Sandbox Code Playgroud)

直到今天我通常使用前者,但我最近发现一些使用后者的代码,似乎这可能是实现它的正确方法.

当对分配给它的外部列表进行更改时,不使用前者会导致更改TheList属性.例如:

List<string> list = new List<string>();
list.Add("Hello");

var c = new someClass();
c.TheList = list;
Run Code Online (Sandbox Code Playgroud)

使用前者不会使用以下代码打破TheList的封装:

list.Clear();
Run Code Online (Sandbox Code Playgroud)

现在c.TheList也是空的,这可能不是我们想要的.但是,使用后一种方法,c .List不会被清除.

SLa*_*aks 7

集合属性应该只读.

你的财产应该暴露一个Collection<T>,而不是一个List<T>.

编辑:解释:

如果其他代码复制对列表的引用(例如,var list = Thingy.TheList),如果将属性设置为其他列表,则可能会混乱.(它最终将持有一个孤儿)
通常,很少有理由允许人们将属性指向不同的集合实例.

使用Collection<T>而不是List<T>允许您拦截对集合的更改并添加验证或维护父字段.(通过继承Collection<T>和覆盖InsertItem以及其他方法)您甚至可以在shippinga库之后添加此类逻辑,而不会破坏调用代码.

  • 或者公开为`ReadOnlyCollection <T>`,`List <T>`有一个AsReadOnly()方法,以便于返回. (2认同)

Bro*_*sto 6

我相信由于列表是参考对象,您需要做的就是获取参考.所以:

   private List<string> _TheList = new List<string>();
public List<string> TheList
{
    get { return _TheList; }
}
Run Code Online (Sandbox Code Playgroud)

获得引用并对集合进行更改后,您将更改_TheList