公开自定义集合与通用集合的框架设计指南是什么?例如
public class ImageCollection : Collection<Image>
{
...
}
public class Product
{
public ImageCollection {get; set;}
}
VS
public class Product
{
public Collection<Image> Images{get; set;}
}
公开自定义集合与通用集合的框架设计指南是什么?例如
public class ImageCollection : Collection<Image>
{
...
}
public class Product
{
public ImageCollection {get; set;}
}
VS
public class Product
{
public Collection<Image> Images{get; set;}
}
如果您正在构建公共 API,请考虑使用自定义集合以获得以下优势。
可扩展性 - 您可以在将来向您的自定义集合添加功能,而无需更改 API。
向后兼容性 - 您可以随意更改集合类的内部结构,而不会破坏客户针对集合编写的现有代码。
以较小的影响进行潜在的破坏性更改也更容易。也许稍后您决定不希望它是一个Collection<Image>
,而是一个不同的集合类型 - 您可以定制您的ImageCollection
类以具有与以前相同的方法,但从不同的东西继承 - 并且客户端代码不太可能中断。
如果它只是用于内部使用的代码,那么这个决定并不一定那么重要,你可能会决定“越简单越好”。
我想到的一个例子是 ESRI 的 ArcGIS Server API——他们在他们的 API 中使用自定义集合。我们也在我们的 API 中使用自定义集合,主要是出于这些原因。
通常,最好公开其中一个接口,例如IEnumerable<T>
,ICollection<T>
或者IList<T>
代替具体的类。
这为您在更改内部 API 方面提供了更大的灵活性。 IEnumerable<T>
,特别是,允许您稍后修改内部结构以允许结果流,因此是最灵活的。
如果您知道“集合”的预期使用模式,您应该公开适当的 API,以便将来对您提供最少的限制。例如,如果您知道人们只需要迭代您的结果,则公开IEnumerable<T>
,因此您可以稍后更改为 ANY 集合,甚至直接切换为仅使用 yield return。
我会去第二个。无论如何,客户端代码都必须知道 Image 类型。
第一个只意味着更多的代码。
我能想到的主要原因是您可能希望有一些特定于图像集合的方法,这些方法可以在该集合本身上运行。然后我会使用 ImageCollection 类来包含这些方法。经典封装。
另外,顺便说一句,您实际上应该只为该集合公开一个 getter,并使用实际集合初始化一个只读支持字段。您可能希望人们向集合中添加/删除项目,而不是替换整个项目:
class Product {
private readonly Collection<Image> _images;
public Product() { _images = new Collection<Image>(); }
public Collection<Image> Images { get { return _images; } }
}
-Oisin
使用的唯一原因Collection<T>
是,如果您想挂接到一组虚拟方法中,它允许您查看底层列表的所有突变。这允许您执行诸如响应删除、实现事件等操作...
如果您对响应或观看这些集合修改不感兴趣,那么 aList<T>
是更合适的类型。
我更喜欢有一个公共的通用属性来使内部可扩展,但私有字段将是具有实际功能的自定义字段。
它通常看起来像这样:
public interface IProduct
{
ICollection<Image> Images { get; }
}
public class Product : IProduct
{
private class ImageCollection : Collection<Image>
{
// override InsertItem, RemoveItem, etc.
}
private readonly ImageCollection _images;
public ICollection<Image> Images
{
get { return _images; }
}
}
我还经常将自定义集合类嵌套在不同的类中,这允许我在添加/删除期间修改父类的一些私有成员。