包装嵌套集合

时间:2010-01-15 17:22:45

标签: c# oop

我目前正在为我们刚刚购买的第三方组件(不是最好的主意,我知道)开发一个包装器,一个精确的网格。好吧,暴露大多数网格属性到目前为止并不那么难......我真正的问题是行/单元集合。

老年人/潜在客户不希望开发人员对其中的所有内容感到疯狂,因此有一些CustomRowCollection的CustomRow对象包含了实际网格的Row对象RowCollection的最低限度是他们的想法...同样适用于单元格,CustomRow对象应该包含CustomCells的CustomCellCollection,其中包含实际的gridrow的Cell对象的CellCollection。

您对我应该如何处理这个问题有什么建议吗?我无法想象设计。 感谢

1 个答案:

答案 0 :(得分:1)

CustomRowCollectionRowCollection的包装。它根本不是一个集合;它是一个实现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);