You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin C#应用生成双份符号列表时偶发数组越界异常求助

解决System.IndexOutOfRangeException的问题

嘿,我一眼就瞅出你代码里的问题所在了!咱们一步步拆解来看:

首先看你报错的那行代码:

letras[i] = Convert.ToString(simbolo)[alea.Next(0, simbolo.Length)];

这里犯了一个很典型的错误:Convert.ToString(simbolo)并没有帮你取出数组里的单个符号,而是把整个simbolo数组对象转换成了字符串,结果会是类似"System.String[]"这样的内容。当你用alea.Next(0, simbolo.Length)生成0到15之间的随机数时,这个字符串的长度远小于16(比如"System.String[]"只有14个字符左右),一旦随机数超过这个字符串的最大索引,就会直接抛出IndexOutOfRangeException——这就是为啥你的代码有时正常有时报错,完全看随机数有没有踩中超出范围的情况。

正确的写法&优化方案

你的需求是生成每个符号恰好出现两次的随机列表,原来的随机选取逻辑其实也有问题(可能导致某个符号出现次数不是2次),正确的做法应该是先对simbolo数组进行洗牌,这样既能保证每个符号的出现次数,又能实现随机顺序。

修正后的代码示例:

// 注意:Random实例最好只初始化一次,避免重复创建导致随机数序列重复
Random alea = new Random();

static int[] letras = new int[16]; 
string[] simbolo = new string[]{"A","B","A","B","C","D","C","D","E","F","E","F","G","H","G","H"}; 

// 用Fisher-Yates洗牌算法打乱数组顺序,保证每个元素出现两次且随机
for (int i = simbolo.Length - 1; i > 0; i--)
{
    int j = alea.Next(0, i + 1);
    // 交换数组元素
    string temp = simbolo[i];
    simbolo[i] = simbolo[j];
    simbolo[j] = temp;
}

// 将洗牌后的符号转换为int值(这里假设你要取字母的ASCII码,若有自定义映射可替换)
for (int i = 0; i < letras.Length; i++)
{
    letras[i] = (int)simbolo[i][0];
    // 如果是自定义数字映射(比如A=1、B=2),可以用switch或字典实现:
    // letras[i] = simbolo[i] switch { "A" => 1, "B" => 2, ... };
}

关键修正点说明

  • 去掉了错误的Convert.ToString(simbolo),直接通过数组索引simbolo[j]获取目标元素,彻底避免字符串索引越界
  • 采用Fisher-Yates洗牌算法,完美匹配你“每个符号出现两次”的需求,同时保证顺序随机
  • 优化了随机数生成逻辑,洗牌时的随机范围始终在数组有效索引内,不会出现越界问题

内容的提问来源于stack exchange,提问作者Janel Garces

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:27:36