Unity C#开发中如何正确初始化List解决索引越界问题
问题根因
触发索引越界的核心原因是List与数组的初始化、访问逻辑存在本质差异:
- 数组执行
new 类型[长度]初始化时,会一次性分配指定长度的内存空间,所有索引位自动填充类型默认值,初始化完成后即可直接通过索引读写对应位置 - List是动态变长集合,执行
new List<T>()初始化后默认元素个数(即Count属性值)为0。即使你在构造函数中传入容量参数,也只是预分配内部内存、减少后续扩容开销,并不会实际生成可访问的元素。此时直接通过[i]索引器访问不存在的位置,就会抛出"索引超出范围"的错误。
另外你贴的代码存在变量名拼写不一致的问题:声明的集合字段是Stroeallobject,循环内调用的却是Stroealljoint,运行时会触发编译错误或空引用,需要统一命名。
正确实现方案
根据你的使用场景,有两种标准实现方式:
方案1:预分配容量+Add方法新增元素(推荐)
这是最符合List设计逻辑的写法,性能最优:
public List<GameObject> StoreAllObject; public List<Vector3> myvector3; public List<Quaternion> myQuaternion; private void Start() { // 初始化List实例,预分配和待遍历集合一致的容量,避免循环中频繁扩容 myvector3 = new List<Vector3>(StoreAllObject.Count); myQuaternion = new List<Quaternion>(StoreAllObject.Count); for (int i = 0; i < StoreAllObject.Count; i++) { // 用Add方法向List末尾追加元素,不要直接对不存在的索引位赋值 myvector3.Add(StoreAllObject[i].transform.position); myQuaternion.Add(StoreAllObject[i].transform.rotation); } }
注意:构造函数传入的容量参数不会改变
Count值,初始化完成后myvector3.Count依然为0,必须通过Add/Insert等方法添加元素后,对应索引位才可以被访问。
方案2:预填充默认值,复刻数组初始化行为
如果你希望和数组使用逻辑完全一致,初始化后即可直接通过索引赋值,可以在初始化时先填充对应数量的默认值:
private void Start() { // 传入指定长度的同类型数组初始化List,此时List的Count值等于数组长度,所有索引位已存在默认值 myvector3 = new List<Vector3>(new Vector3[StoreAllObject.Count]); myQuaternion = new List<Quaternion>(new Quaternion[StoreAllObject.Count]); for (int i = 0; i < StoreAllObject.Count; i++) { // 此时可以直接通过索引修改对应位置的值,不会触发越界错误 myvector3[i] = StoreAllObject[i].transform.position; myQuaternion[i] = StoreAllObject[i].transform.rotation; } }
这种写法效果和数组初始化完全一致,但不符合List动态集合的设计初衷,除非你有必须按索引随机写入的特殊需求,否则优先选择方案1。
关键规则
List的索引器仅支持修改已经存在的元素,只有当索引i满足0 <= i < List.Count时,list[i] = 赋值的写法才合法。如果是向集合新增元素,需要使用:
Add(元素值):向集合末尾追加元素Insert(索引位置, 元素值):向指定索引位置插入元素
内容的提问来源于stack exchange,提问作者利维坦
相关产品推荐
相关产品推荐

