C#列表之间的一致性

本文关键字:一致性 之间 列表 | 更新日期: 2023-09-27 18:22:08

我正在为XNA编写一个小型游戏引擎。现在,我的实体管理器有一个可以更新和渲染的所有实体的列表。然而,让我们说,我想把这个列表分成"子列表"。也许有些实体不需要渲染,因此我们希望将渲染实体与非渲染实体分开,同时保留另一个显示所有实体以供更新的列表。所以这是3个列表。

有没有一种方法可以轻松地保持列表之间的一致性?确保在两个列表中引用完全相同的对象?(不是对象的副本?)。在C++中,我们只需要一个指向渲染实体的指针数组,另一个则指向不渲染的实体。

问题并不是真的把实体放进这些列表,而是处理它们会让我大吃一惊。要销毁一个实体,我只需在该实体中设置一个"dispose"bool为true。当循环遍历所有实体时,如果"dispose"设置为true,实体管理器会删除对该实体的引用,而垃圾清理器会销毁该实体,因为它没有更多的引用了。我是否必须手动遍历与实体有关的每个列表,并从这些列表中删除该实体,以保持一致?

这个"问题"的另一个例子是四叉树。我有一个2d游戏,我为所有实体生成了一个四叉树。位于两个网格位置之间的实体位于树的两个分支中。我该怎么把它从树上取下来?在整个树中搜索对该实体的引用?如果是这样的话,拥有一棵四叉树似乎有点毫无意义。。!

C#列表之间的一致性

考虑使用一个列表和该列表的两个查询,而不是3个列表。

var list = GetYourMainList(); 
var renderableEntities = list.Where(item => item.IsRenderable); 
var nonrenderableEntities = list.Where(item => !item.IsRenderable); 
// work with the queries
foreach (var item in renderableEntities)
{
    // do whatever
}

在这里,您可以对每个查询进行迭代,结果将从主列表中流出,对该列表的任何更新都将在迭代时反映在查询结果中。需要注意的是,在迭代查询时,不能修改列表(如添加到中或从中删除)。

对于您的处理问题,您可以实现IDisposable。对于您的列表,您可以创建一个包含这两个列表的类,如果您需要整个列表,请实现一个枚举器,该枚举器将枚举这两个名单。

您可以在实体周围放置一个知道它在哪些列表中的包装器,这样当您想要删除它时,可以相对容易地从所有位置同时删除它。

如果您在多个列表中有项目,那么是的,如果您想删除它们,则必须将它们从出现它们的所有列表中删除。一个简单的方法是将删除项的责任分配给项本身:例如,当您对呈现项调用RemoveFromLists()时,呈现项会从呈现项列表中删除自己。

Anthony Pegram所描述的查询的使用消除了这种复杂性,但如果列表很大,则效率低下,因为它们无法增量更新。

至于四叉树,一个简单的方法是让每个项目都保留一个四叉树节点列表(或者,如果你不想在项目中添加字段,请使用字典)。然后很容易将它们从它们在恒定时间内发生的所有节点中删除。

您可以让您的实体公开一个"Disposing"事件,该事件在释放之前被激发。然后,您可以让列表的Add方法向要添加的实体注册一个事件处理程序,该事件处理程序将在释放实体之前从列表中删除该实体。