Подтвердить что ты не робот

Есть ли интерфейс сборника .NET, который предотвращает добавление объектов?

У меня есть класс, который поддерживает список объектов другого класса. Список объектов является публичной собственностью. Я бы хотел, чтобы пользователи не добавляли и не удаляли объекты непосредственно в список:

      MyObject.MyListProperty.Add(object);

Вместо этого я хочу, чтобы они использовали метод, который будет внутренне выполнять некоторую обработку, а затем добавлять объект в список.

У меня есть некоторые идеи:

  • создать потомка List<T> и переопределить добавление и удаление
  • возвращает новую копию списка через свойство getter (список относительно короткий, не более 30 объектов)

Есть ли какой-либо интерфейс коллекции, который не содержит Add and Remove?

Edit:
Я собираюсь пойти с ReadOnlyCollection<T>. Причина в том, что обернутая коллекция может быть обновлена, и изменения будут немедленно видны в объекте только для чтения (см. Примеры кода MSDN для ReadOnlyCollection<T> и AsReadOnly()). Это позволяет создать список только для чтения только один раз.

Проблема с IEnumerable заключается в том, что объект может быть возвращен в исходный List<T>, а затем непосредственно манипулировать.

4b9b3361

Ответ 1

Вы можете использовать ReadOnlyCollection - оберните свою коллекцию в этом и верните ReadOnlyCollection пользователям вашего класса:

return new ReadOnlyCollection(innerCollection);

Или используя метод AsReadOnly класса List<T>:

return innerCollection.AsReadOnly();

Интерфейс IEnumerable будет делать то, что вам нужно, поскольку он имеет только один элемент GetEnumerator(), который позволит вам только перебирать элементы.

Ответ 2

Может быть Метод AsReadOnly сделает трюк, чтобы передать экземпляр только для чтения публике.

В противном случае IEnumerable<T> не имеет Add и Remove, поэтому вы можете сделать что-то вроде:

private List<int> _myList;
public IEnumerable<int> MyList
{
   get
   {
      return this._myList.ToList();
   }
}

Я предпочитаю использовать IEnumerable<T> (+ copy) как для ReadOnlyCollection<T>, потому что: изменения в базовом списке (который создается из вашей коллекции только для чтения) будут немедленно отображаться в вашем экземпляре прочитанного единственная коллекция. это может вызвать проблемы с фиксацией и перемещением:)

Ответ 3

Самый простой способ - разоблачить свой список как один из следующих IEnumerable, ICollection ReadOnlyCollection через общедоступное свойство.

Итак, вы можете создать свой собственный type списка, который предоставляет ваш Items как один из приведенных выше, но имеет внутренний метод добавления, например.

public class MyList<MyType>
{
    private List<MyType> items;

    public MyList()
    {
        items = new List<MyType>();
    }

    public IEnumerable Items { get { return items.AsEnumerable(); } }
    public Add(MyType item)
    {
        // do internal processing
        items.Add(item);
    }
}

Ответ 4

Из коробки только IEnumerable<T> предоставит это, не подвергая никаким общедоступным методам Add и Remove, которые могут обмануть клиента в получении исключения во время выполнения.

Если вы хотите, чтобы ваш публичный API явно указывал, что коллекция доступна только для чтения, и вам нужен указатель, вам придется написать свою собственную оболочку вокруг существующих List<T> или T[].

Ответ 5

Вы могли бы просто дать им объект, который всегда возвращает перечислитель, который они могут использовать для доступа к структуре?

Ответ 6

Не отвечает на ваш вопрос, но полезная информация, если вы решите реализовать одну из двух своих идей: Вы можете использовать ToArray для создания копии и возврата массива.

Или вы можете сделать что-то вроде этого: http://en.csharp-online.net/CSharp_Generics_Recipes%E2%80%94Making_Read-Only_Collections_the_Generic_Way

Ответ 7

ICollection (не общая версия) получил только IEnumerable + Count