Как сделать метод Add List защищенным, в то же время выставляя List с помощью свойства get? - PullRequest
16 голосов
/ 16 июля 2010

У меня есть класс с именем WhatClass, в котором есть поле List. Мне нужно, чтобы это поле было доступно только для чтения, поэтому я использовал свойство get, чтобы показать его другим объектам.

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems; } }
}

Однако оказывается, что любой объект может вызвать

WhatClass.SomeOtherClassItems.Add(item);

Как я могу предотвратить это?

Ответы [ 5 ]

25 голосов
/ 16 июля 2010

Как уже говорили другие, вы ищете метод расширения .AsReadOnly().

Однако вы должны хранить ссылку на коллекцию, а не создавать ее при каждом доступе к свойству:

private readonly List<SomeOtherClass> _items;

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

    this.Items = _items.AsReadOnly();
}

public ReadOnlyCollection<SomeOtherClass> Items { get; private set; }

Это сделано для того, чтобы x.Items == x.Items выполнялось, что в противном случае могло бы быть очень неожиданным для потребителей API.

Предоставление ReadOnlyCollection<> сообщает потребителям о вашем намерении создать коллекцию только для чтения.Изменения в _items будут отражены в Items.

7 голосов
/ 16 июля 2010

Вы ищете класс 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; }
}
6 голосов
/ 16 июля 2010

Использовать List<T>.AsReadOnly:

public ReadOnlyCollection<SomeOtherClass> SomeOtherClassItems
{
    get
    {
        return _SomeOtherClassItems.AsReadOnly();
    }
}

Это вернет ReadOnlyCollection , которое вызовет исключение, если клиент вызовет Add через интерфейс.Кроме того, тип ReadOnlyCollection не предоставляет открытый метод Add.

3 голосов
/ 16 июля 2010

Как насчет использования AsReadOnly()?- Документация MSDN

0 голосов
/ 11 июля 2019

Вы можете просто использовать ToList (), чтобы вернуть копию списка. Другие классы могут делать то, что им нравится, с копией, это не изменит ваш первоначальный список.

Вы должны четко указать от имени, что они получают копию.

using System.Linq;

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems.ToList(); } }
}
...