using Fantasy.Entitas; #pragma warning disable CS8603 // Possible null reference return. namespace Fantasy; public static class ItemFactory { /// /// 创建一个物品 /// /// /// /// /// /// public static Item Create(Scene scene, uint configId, int count, bool isBind) { var itemConfig = ItemConfigData.Instance.Get(configId); if (itemConfig.Superposed) { if (itemConfig.SuperposedMax < count) { Log.Error($"物品{itemConfig.Name} 最大叠加数量为{itemConfig.SuperposedMax},不能超过{count}"); return null; } } else { if (count > 1) { Log.Error($"物品{itemConfig.Name} 不支持叠加,不能超过1个"); return null; } } var item = Entity.Create(scene, true, true); item.ConfigId = configId; item.Count = count; item.IsBind = isBind; // 根据物品的类型单独的做一些处理 switch ((ItemType)itemConfig.Type) { case ItemType.Drug: { break; } case ItemType.Equip: { // 装备的要挂载装备组件。 item.AddComponent(); break; } case ItemType.Prop: { break; } case ItemType.Garbage: { break; } } return item; } /// /// 批量创建物品 /// /// /// /// public static void Create(Scene scene, List itemCreateParamsList, List items) { // 也可以用Foreach,但是性能会差一点点。 // for和Foreach性能差距非常小,尤其是在现在的CPU用,但如果在高频繁使用的场景下,for提升会明显一些。 // 不要纠结到底是用for还是Foreach,因为两者性能差距非常小,而且Foreach更简洁。 // 以下是一个简单性能对比(处理 1000 万元素的 List): // for 循环 ~50 ms // foreach 循环 ~70 ms // for 循环快约 20-30%(因硬件和 .NET 版本而异)。 // 为什么 for 更快? // 直接索引访问:List 底层是数组,索引访问是 O(1) 操作。 // 避免迭代器开销:foreach 需要调用 MoveNext() 和 Current,隐含版本检查(防止遍历时集合被修改)。 // 什么时候用 foreach? // 代码简洁性优先:不需要索引时,foreach 更易读。 // 复杂集合类型:对于非 List 的集合(如 IEnumerable 或字典),foreach 可能更高效,因为某些集合的索引访问是 O(n)(如 LinkedList)。 // 优化建议 // 优先选择 for:如果性能敏感且需要高频遍历大规模数据。 // 使用 foreach:如果代码可读性更重要,或遍历非数组结构的集合。 // 避免在 List 中使用 foreach 的陷阱: // 如果遍历过程中修改集合(如增删元素),会触发 InvalidOperationException。 // 对值类型集合(如 List),foreach 可能涉及装箱(但 List 的 Enumerator 是结构体,不会发生装箱)。 // 高级场景 // Span 或数组:对于 Span 或原生数组,for 循环可以进一步优化为 SIMD 指令。 // for (var index = 0; index < itemCreateParamsList.Count; index++) // { // var itemCreateParams = itemCreateParamsList[index]; // var item = Create(scene, itemCreateParams.ConfigId, itemCreateParams.Count, itemCreateParams.IsBind); // items.Add(item); // } foreach (var itemCreateParams in itemCreateParamsList) { var item = Create(scene, itemCreateParams.ConfigId, itemCreateParams.Count, itemCreateParams.IsBind); items.Add(item); } } }