【发布时间】:2015-04-18 14:44:35
【问题描述】:
我有一个类,它封装了我们称之为ItemCollection 的项目集合。我需要公开两个不同的枚举器来处理这个集合:一个简单地枚举所有项目(Item),第二个只枚举那些是特定派生类型的项目(T where T:Item)。一个问题是,这部分实时库代码在紧凑框架上运行,它确实需要避免在堆上分配对象,这可能会在 foreach 循环中间触发一个集合。我一直在使用 struct Enumerators 来满足这个要求。
public class ItemCollection
{
public ItemEnumerator GetEnumerator() {}
public ItemGenericEnumerator<T> GetEnumerator<T>() {} // Probably not correct
}
public struct ItemEnumerator : IEnumerator<Item>
{
Item Current;
bool MoveNext() {}
void Reset() {}
}
public struct ItemGenericEnumerator<T> : IEnumerator<T> where T : Item
{
T Current;
bool MoveNext() {}
void Reset() {}
}
从表面上看,我不知道如何对GetEnumerator<T> 进行特定调用,实际上我是从这个开始的:
public class ItemCollection
{
public ItemEnumerator GetEnumerator() {}
public ItemGenericEnumerator<T> ItemsOfType<T>() {}
}
foreach(var item in collection.ItemsOfType<X>)
但我立即遇到了does not contain a public definition for 'GetEnumerator'。
一个解决方案是让 ItemsOfType 返回一个通用的丢弃类,该类具有一个接收枚举器和单个 GetEnumerator 方法的构造函数,但该实现打破了无堆分配要求(返回另一个带有 GetEnumerator 结构的丢弃结构会起作用吗? )。
另一个废弃的选项是简单地使用第一个枚举器并要求手动检查类型,它只是一行额外的代码。然而,目前 ItemCollection 的实现细节意味着,仅返回一种类型的项目与拉出所有项目然后在框外排序之间存在很大差异。
【问题讨论】:
-
在您的
ItemCollection中保存Item或派生T项目的底层存储容器是什么? -
一个链接列表和不安全代码的网络,将来自许多集合的项目混合在一起,旨在接近硬件 API。 ItemCollection 是一种弥合代码安全部分和不安全部分之间差距的方法。明智的实施更接近于说项目是按类型在内部分组而不是按集合,这就是为什么 ItemsOfType 更快(直接转到一组类型的项目,然后按关联的集合 id 过滤)然后很少使用的“全部”必须遍历内存中的每一项。我认为导致结构的丢弃结构可能是关键。
标签: c# generics compact-framework enumeration