如何在函数中高级使用List?Unity对象池通用化实现疑问
问题
我正在用类的静态List实现对象池,想简化/通用化对象池函数来减少重复代码。目前每种资源(比如Iron、Coal)都要单独写Get函数,每次都是复制修改:
public static List<Resources> allResources = new List<Resources>(); public static List<Resources> allIron = new List<Resources>(); // Iron.cs是子类 public static List<Resources> allCoal = new List<Resources>(); // Coal.cs是子类 public Iron GetIron(Vector3 position) { if (allIron.Count > 0) { for (int i = 0; i < allIron.Count; i++) { if (!allIron[i].gameObject.activeSelf) { allIron[i].trans.position = position; allIron[i].gameObject.SetActive(true); return (Iron)allIron[i]; } } } Instantiate(prefabIron, position, Quaternion.identity, oreHolder.transform); return (Iron)allIron[allIron.Count - 1]; }
我想写一个通用函数替代这些重复代码,写了下面的版本,但没法正常工作——传入的List好像只是副本,没法修改原静态List里的实体。请问能不能实现这种通用函数?必须每种资源单独写函数吗?
注:我可以遍历allResources,但这个List里有10万+元素,遍历性能太差,所以按资源类型拆分List来减少遍历次数。另外我已经自己找到答案了,感谢回复者。
解答
当然可以实现通用函数,你之前的问题不是List传参的问题(C#里List是引用类型,传参时传递的是引用,不是副本),问题出在实例化后没有把新对象添加到对应的静态List里,还有返回值的类型转换可以通过泛型来处理。
这里提供一个基于泛型的通用实现:
// 泛型通用获取函数 public T GetResource<T>(List<Resources> resourceList, Vector3 position, GameObject prefab) where T : Resources { // 遍历找闲置对象 if (resourceList.Count > 0) { foreach (var res in resourceList) { if (!res.gameObject.activeSelf) { res.trans.position = position; res.gameObject.SetActive(true); return res as T; } } } // 实例化新对象 var newObj = Instantiate(prefab, position, Quaternion.identity, oreHolder.transform); var newResource = newObj.GetComponent<T>(); // 把新对象加入对应的类型List和总List resourceList.Add(newResource); allResources.Add(newResource); return newResource; }
调用的时候就可以这样用:
// 获取Iron Iron iron = GetResource<Iron>(allIron, position, prefabIron); // 获取Coal Coal coal = GetResource<Coal>(allCoal, position, prefabCoal);
关键点说明
- 泛型约束:
where T : Resources确保传入的类型是Resources的子类,保证类型安全。 - 引用类型传参:List是引用类型,函数里对resourceList的操作(比如Add)会直接作用于原静态List,不存在副本问题。
- 显式添加实例:之前的代码里调用Instantiate后没有手动添加到对应List,导致
resourceList[resourceList.Count - 1]取不到新对象,现在实例化后主动把组件加入List就解决了这个问题。 - 性能保持:依然是按类型List遍历,不会影响10万+元素的总List性能。
内容的提问来源于stack exchange,提问作者WideEyeNow
相关产品推荐
相关产品推荐

