Существует ли интерфейс набора.NET, который предотвращает добавляющие объекты?

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

      MyObject.MyListProperty.Add(object);

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

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

  • создайте потомка List и переопределение добавляет и удаляет
  • возвратите новую копию списка через метод считывания свойства (список относительно короток, не больше чем 30 объектов),

Там некоторый набор является интерфейсом, который не имеет, Добавляют и Удаляют?

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

Проблема с IEnumerable тот объект, может быть литая спина к оригиналу List и затем непосредственно управляемый.

24
задан Peter Mortensen 2 February 2010 в 18:25
поделиться

7 ответов

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

return new ReadOnlyCollection(innerCollection);

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

return innerCollection.AsReadOnly();

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

36
ответ дан 28 November 2019 в 23:18
поделиться

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

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

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

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

.
5
ответ дан 28 November 2019 в 23:18
поделиться

Зависит от требуемой информации. Для отладки трассировки стека и внутренних исключений рекомендуется:

    string message =
        "Exception type " + ex.GetType() + Environment.NewLine +
        "Exception message: " + ex.Message + Environment.NewLine +
        "Stack trace: " + ex.StackTrace + Environment.NewLine;
    if (ex.InnerException != null)
    {
        message += "---BEGIN InnerException--- " + Environment.NewLine +
                   "Exception type " + ex.InnerException.GetType() + Environment.NewLine +
                   "Exception message: " + ex.InnerException.Message + Environment.NewLine +
                   "Stack trace: " + ex.InnerException.StackTrace + Environment.NewLine +
                   "---END Inner Exception";
    }
-121--630105-

См. эту статью о ProductCode и PackageCode: http://www.simple-talk.com/dotnet/visual-studio/updates-to-setup-projects/

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

-121--4501564-

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

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

2
ответ дан 28 November 2019 в 23:18
поделиться

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

-121--3429425-

Предотвращение вызова оператором-запятой перегрузок оператора

Иногда используется оператор-запятая, но необходимо убедиться, что ни один оператор-запятая, определенный пользователем, не попадает в путь, так как, например, вы полагаетесь на точки последовательности между левой и правой сторонами или хотите убедиться, что ничего не мешает требуемому действию. Здесь void () вступает в игру:

for(T i, j; can_continue(i, j); ++i, void(), ++j)
  do_code(i, j);

Игнорируйте места, которые я ставлю для условия и кода. Что важно, так это void () , который заставляет компилятор использовать оператор builtin. Иногда это может быть полезно и при реализации классов признаков.

-121--690068-

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

0
ответ дан 28 November 2019 в 23:18
поделиться

Iconlication (нереборежественная версия) только INumerable + Count

0
ответ дан 28 November 2019 в 23:18
поделиться

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

Таким образом, вы можете создать свой собственный тип списка, который предоставляет ваши 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);
    }
}
5
ответ дан 28 November 2019 в 23:18
поделиться

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

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

0
ответ дан 28 November 2019 в 23:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: