检查列表中是否有已删除的插槽



我想生成一些带有ID的ItemsItem只是一个具有ID integer属性的类。它们应该在创建后添加到列表中。所以我有一个管理所有项目的类

internal static class ItemPool
{
public static readonly List<Item> items = new List<Item>(); // Store all the items here
public static Item CreateItem()
{
int itemId = items.Count; // Just take the next free slot index
Item itemToCreate = new Item(itemId);
items.Add(itemToCreate);
return itemToCreate;
}
public static void DestroyItem(int itemId)
{
activeItems.RemoveAt(itemId);
}
}

现在我可以创建一些项目

Item firstItem = ItemPool.CreateItem(); // generates item with ID 0
Item secondItem = ItemPool.CreateItem(); // generates item with ID 1
ItemPool.DestroyItem(firstItem.id); // Recudes the list count to 1
Item thirdItem = ItemPool.CreateItem(); // generates item with ID 1 - ERROR

第三个项目不允许具有ID 1,因为项目2已经具有该ID。

当更改代码时,会出现两个问题:

如何管理此列表中项目的ID,使它们都没有相同的ID?

public static Item CreateItem()
{
int itemId = temporaryUniqueId; // create a temporary unique ID
// ... other code
}

什么是比更优化的方法

public static void DestroyItem(int itemId)
{
activeItems = activeItems.Where(item => item.id != itemId).ToList();
}

我知道我可以做

public static void DestroyItem(Item item)
{
activeItems.Remove(item);
}

但我认为通过ID删除更安全。我之所以这么问,是因为在这种情况下,性能就是一切

ID不必是整数值

由于不需要将ID作为整数,因此一种方法是使用GUID作为唯一标识符,以避免处理潜在的冲突。

public class Item 
{
public Guid Id { get; }
public Item()
{
Id = Guid.NewGuid();
}
}

然后,您的ItemPool类可以更改为使用ConcurrentDictionary(以避免任何比赛条件(:

internal sealed class ItemPool
{
private readonly ConcurrentDictionary<Guid, Item> items = new ConcurrentDictionary<Guid, Item>(); // Store all the items here
public Item CreateItem()
{
Item itemToCreate = new Item();
items.TryAdd(itemToCreate.Id, itemToCreate);
return itemToCreate;
}
public void DestroyItem(Guid itemId)
{
activeItems.TryRemove(itemId, out Item _);
}
}

我随意删除了类的静态参数,以便于测试。为了更好地封装,我还将items字段设为私有字段。您不希望任何其他类绕过ItemPool并开始自己操作集合:(

最新更新