C#运行报Array Index out of range数组索引越界异常排查
问题根因
报错是C#闭包对循环变量的捕获机制导致的:
- 你给按钮绑定的匿名委托,捕获的是外层循环变量
i和内层循环变量m本身,而不是循环执行到当前轮次时i、m的具体值。 - 两层循环全部执行完成后,
i的值会等于bookCatogaryObject.Data.Rows.Count(已经超出DataClassArray的合法索引范围,数组最大合法索引是数组长度减1),m的值也会等于对应内层数组的长度,同样超出合法索引范围。 - 当你后续点击按钮触发委托逻辑时,代码会用循环结束后的越界索引去访问数组,直接抛出
IndexOutOfRangeException。 - 额外存在一个潜在问题:你当前代码只初始化了
collectionDataClass数组本身,没有为数组内的每个CollectionDataClass元素实例化对象,后续访问元素的属性时还会触发空引用异常。
修复方案
在循环的当前迭代作用域内声明临时变量,存储当前条目的目标值,让闭包捕获这个固定的临时变量即可,不要直接在委托里使用循环迭代变量。
修复后的核心代码片段如下:
for (int i = 0; i < bookCatogaryObject.Data.Rows.Count; i++) { DataClassArray[i] = new DataClass(); int rowItemCount = bookCatogaryObject.Data.Rows[i].String.Count; DataClassArray[i].collectionDataClass = new CollectionDataClass[rowItemCount]; DataClassArray[i].categaryPrefabObject = bookCatogaryPrefabObjects[i]; for (int m = 0; m < rowItemCount; m++) { // 先实例化数组元素,避免后续触发空引用异常 DataClassArray[i].collectionDataClass[m] = new CollectionDataClass(); // 省略原有生成GameObject、设置组件、赋值sprite的逻辑... // 声明临时变量存储当前条目id,闭包会捕获这个固定值 string targetId = DataClassArray[i].collectionDataClass[m].id; collectionImageContainer.GetComponent<JMRUIPrimaryButton>() .OnClick.AddListener(delegate () { OnClickEvent(targetId); }); } }
内容的提问来源于stack exchange,提问作者Omkar P
相关产品推荐
相关产品推荐

