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);