我想生成一些带有ID的Items
。 Item
只是一个具有ID整数属性的类。创建它们后,应将它们添加到列表中。所以我有一堂课来管理所有项目
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不必为整数值
答案 0 :(得分:2)
由于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
并开始自己操纵集合:)