如何在使用get属性公开List的同时使List的Add方法受到保护?

Nik*_*vić 19 c# properties list

我有一个名为WhatClass的类,其中包含List字段.我需要能够只读这个字段,所以我使用get属性将它暴露给其他对象.

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems; } }
}
Run Code Online (Sandbox Code Playgroud)

然而事实证明任何对象都可以调用

WhatClass.SomeOtherClassItems.Add(item);
Run Code Online (Sandbox Code Playgroud)

我怎么能阻止这个?

Bry*_*tts 27

正如其他人所说,您正在寻找.AsReadOnly()扩展方法.

但是,您应该存储对集合的引用,而不是在每次属性访问期间创建它:

private readonly List<SomeOtherClass> _items;

public WhatClass()
{
    _items = new List<SomeOtherClass>();

    this.Items = _items.AsReadOnly();
}

public ReadOnlyCollection<SomeOtherClass> Items { get; private set; }
Run Code Online (Sandbox Code Playgroud)

这是为了确保x.Items == x.Items保持为true,否则API消费者可能会非常意外.

公开将ReadOnlyCollection<>只读集合的​​意图传达给消费者.变化_items将反映在Items.

  • @Dave - 文档声明更改将反映在包装器中. (2认同)

SLa*_*aks 8

你正在寻找这个ReadOnlyCollection<T>,它是一个只读的包装器IList<T>.

由于ReadOnlyCollection<T>将反映基础列表中的更改,因此您不需要每次都创建新实例.

例如:

public class WhatClass {
    public WhatClass() {
        _SomeOtherClassItems = new List<SomeOtherClass>();
        SomeOtherClassItems = _SomeOtherClassItems.AsReadOnly();
    }

    List<SomeOtherClass> _SomeOtherClassItems;

    public ReadOnlyCollection<SomeOtherClass> SomeOtherClassItems { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)


Qua*_*ter 6

用途List<T>.AsReadOnly:

public ReadOnlyCollection<SomeOtherClass> SomeOtherClassItems
{
    get
    {
        return _SomeOtherClassItems.AsReadOnly();
    }
}
Run Code Online (Sandbox Code Playgroud)

这将返回一个ReadOnlyCollection,如果客户端通过接口调用Add,则会抛出异常.此外,ReadOnlyCollection类型不公开公共Add方法.

  • 不要每次都创建一个新实例. (6认同)
  • 在属性getter中分配对象是个坏主意.人们通常认为访问属性getter只不过是一个内存读取,因此将在大型嵌套循环中多次访问该属性. (2认同)