我有一个针对内部各种事物的通用集合实现:
public class ImageDocument
具有以下属性:
.Objects
.Effects
.Layers
每个基本上都是IEnumerable<T>
,但我也有单独的调用,这些调用可以让我计算每一个,例如:
GetNumObjects()
GetNumEffects()
GetNumLayers()
但是这些是我想要包装的低级别成员,以及将上述属性(.Objects, .Effects, .Layers
)实现为IEnumerable<T>
,也使用较低级别的成员,如:
GetObject (int index)
GetEffect (int index)
GetLayer (int index)
我有自己的IEnumerable<T>
类接口,它继承自IEnumerable<T>
。
最后我希望这些属性如下:
ICountableEnumerable Objects
ICountableEnumerable Effects
ICountableEnumerable Layers
所以我可以枚举它们,访问它们的计数(使用低级函数)以及能够索引它们:
myImageDocument.Objects.Count, etc.
myImageDocument.Objects[4]
foreach ... myImageDocument.Objects ...
我可以直接实现这些,就像在IEnumerable<T>
中实现ImageDocument
一样:
public IEnumerator<Objects> GetEnumerator()
{
foreach(...)
{
yield return obj;
}
}
或者我是否需要每种属性的中间类型?类似的东西:
ObjectCollection
EffectCollection
LayerCollection
实现ICountableEnumerable
?
答案 0 :(得分:4)
我可能会这样做:
class ImageDocument
{
public ReadOnlyCollection<Effect> Effects { get { ... } }
public ReadOnlyCollection<Layer> Layers { get { ... } }
...
这样用户就可以使用ReadOnlyCollection的所有优秀属性,比如count等。只读集合是一个围绕可变集合的包装器;你可以让你的可变集合逻辑作为一个实现细节工作,只是在它上面展示一个只读的包装器。
答案 1 :(得分:2)
如果你的课程中你把馆藏作为List&lt; T&gt;?然后你的IEnumerable&lt; T> .Objects等可以返回List,它将是可枚举的,并且可以通过LINQ对索引和计数进行优化。
答案 2 :(得分:1)
我建议为每种不同的枚举样式声明一个结构类型; struct应该包含对基本集合的不可变引用,并实现IEnumerable&lt; properType&gt;并公开公开一个GetEnumerator方法,该方法又会调用baseThing.GetLayersEnumerator()或其他一些类似的函数。这种方法可以避免在许多常见的使用场景中进行装箱,并且 - 与List.GetEnumerator之类的东西返回的结构不同 - 将显示引用语义,无论它是否已装箱。