Упаковка вложенной коллекции - PullRequest
0 голосов
/ 15 января 2010

В настоящее время я работаю над оболочкой для стороннего компонента (не самая лучшая идея, я знаю), который мы только что приобрели, а точнее - сетка. Что ж, раскрыть большинство свойств сетки пока не сложно, моя настоящая проблема с коллекцией строк / ячеек.

Пожилые люди / лидеры не хотят, чтобы разработчики сходили с ума от всего этого, поэтому их идея заключается в том, чтобы иметь своего рода CustomRowCollection объектов CustomRow, оборачивающих минимум объектов RowCollection of Row фактической сетки ... то же самое касается ячеек объект CustomRow должен иметь CustomCellCollection of CustomCells, охватывающий фактическую ячейку ячейки CellCollection объектов Cell.

Есть ли у вас какие-либо советы о том, как я должен подходить к этому? Я не могу представить себе дизайн. Спасибо

1 Ответ

1 голос
/ 15 января 2010

CustomRowCollection - это обертка вокруг RowCollection. На самом деле это не коллекция; это класс, который реализует ICollection<CustomRow> и переводит каждый метод в соответствующий метод в базовом RowCollection. Например:

public void Add(CustomRow r)
{
   _RowCollection.Add(r.Row);
}

Проблема с этим очевидна, если вы посмотрите, скажем, на индексатор:

public CustomRow this[int i]
{
   get { return new CustomRow(_RowCollection[i]); }
   set { _RowCollection[i] = value.Row; }
}

Вы создаете новый объект CustomRow каждый раз, когда получаете CustomRow из CustomRowCollection. Это может вызвать много проблем. Например, это не удастся, и это действительно не должно:

Debug.Assert(myCustomRowCollection[0] == myCustomRowCollection[0]);

Есть несколько способов обойти это. Вы можете скрыть RowCollection с помощью частного Dictionary<Row, CustomRow> поля. Ваш индексатор будет выглядеть так:

public CustomRow this[int i]
{
   get
   {
      Row r = RowCollection[i];
      if (!_Dictionary.ContainsKey(r))
      {
         _Dictionary[r] = CustomRow(r);
      }
      return _Dictionary[r];
   }
   set
   {
      _Dictionary[value.Row] = value;
      RowCollection[i] = value.Row;
   }
}

Это предотвращает создание двух CustomRow объектов с одним и тем же базовым Row. Но это большая работа, потому что вам приходится иметь дело с синхронизацией этих коллекций друг с другом. (Это особенно плохо, если сетка удаляет Row из RowCollection без уведомления вас, потому что вы по-прежнему сохраняете ссылку на этот Row в своем словаре и ничего, кроме повторной синхронизации вашего словаря с RowCollection когда-нибудь удалит его.)

Более простой способ - переопределить Equals в классе CustomRow, чтобы два объекта CustomRow были равны, если их свойства Row равны. Вы также должны переопределить GetHashCode, чтобы он возвращал Row.GetHashCode(), что позволит вам использовать CustomRow объекты в качестве словарных ключей.

Вы должны быть очень осторожны, если вы делаете это, чтобы никогда не реализовывать какие-либо свойства в CustomRow, которые не являются оболочками вокруг свойств в Row. Если вы когда-либо делаете это, вы вводите ситуацию, в которой это может не сбоить, и это всегда должно:

Debug.Assert(r1 == r2 && r1.Property != r2.Property);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...