C#中while循环内空try-catch捕获IndexOutOfBoundsException是否合法?
问题整理
我正在完成一个未完成的C# WinForms游戏存档编辑器项目,发现角色头像与图标的ID有效范围为1至905,但原代码未对该范围进行验证,因此我编写了修复代码(部分函数名已脱敏)。目前因缺少WinForms数据无法编译测试,想确认:
- 在while循环内的if语句末尾使用空try-catch捕获
System.IndexOutOfBoundsException是否合法? - 若该异常选型不合适,应选用哪种异常?
- 若while循环的使用方式不当,如何在不重写整个代码块的前提下调整?
我期望当ID大于905时抛出IndexOutOfBoundsException,否则读取正确的图像文件。后续我根据反馈修改了代码,希望当ID>905时弹出异常提示存档可能损坏,且程序能继续运行,想确认该修改是否合理。
初始代码
void getImage(int slot) { short ID = 0; if (slot == 1) { try { ID = convertStringtoID(comboBoxSlot1ID.Text); } catch (System.FormatException) { ID = 0; } while (ID > 0 && ID < 906) { if (ID < 10) { pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject("00" + ID); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon00" + ID); } else if (ID > 9 && ID < 100) { pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject("0" + ID); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon0" + ID); } else if (ID > 99 && ID < 906) { pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject("" + ID); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon" + ID); } else { try { } catch (System.IndexOutOfRangeException) { ID = 0; } } } } }
修改后代码
void getImage(int slot) { short ID = 0; if (slot == 1) { try { ID = convertStringtoID(comboBoxSlot1ID.Text); } catch (System.FormatException) { ID = 0; } if (ID < 10) { pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject("00" + ID); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon00" + ID); } else if (ID > 9 && ID < 100) { pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject("0" + ID); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon0" + ID); } else if (ID > 99 && ID < 906) { pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject("" + ID); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon" + ID); } else if (ID > 905) { throw(System.InvalidOperationException); ID = 0; continue; } } }
问题解答
1. 空try-catch捕获System.IndexOutOfBoundsException是否合法?
语法上合法,但完全无意义。空try块里没有任何执行代码,根本不会触发任何异常,对应的catch块永远不会被执行,属于纯冗余代码。
2. 异常选型是否合适?
IndexOutOfRangeException是用于数组、集合等索引越界场景的异常,和你的ID超出有效范围的场景不匹配。更合适的选择是:
ArgumentOutOfRangeException:专门用于参数值超出预设有效范围的场景,完全贴合你的ID验证需求;- 如果需要更明确的业务提示,也可以自定义异常,但简单场景下
ArgumentOutOfRangeException足够清晰。
3. while循环的使用问题及调整
原代码中的while (ID > 0 && ID < 906)完全多余:ID是固定值(循环内没有修改ID的有效逻辑),这个循环要么只执行一次,要么完全不执行,根本达不到循环的目的。
调整方式:直接删除while循环,把内部逻辑直接放在if(slot==1)的代码块里即可——你的需求是根据ID区间执行一次图像加载,不需要循环结构。
修改后代码的合理性分析
修改后的代码存在多处问题,不合理:
throw(System.InvalidOperationException);语法错误,正确写法是throw new System.InvalidOperationException("存档可能损坏,ID超出有效范围(1-905)");,必须实例化异常对象;throw语句后的ID = 0;和continue;永远不会执行,因为抛出异常后程序会直接跳出当前方法;continue无意义,当前代码已经没有循环结构;- 未处理ID=0的情况,原代码中ID=0时不会进入循环,修改后ID=0时什么都不会做,建议补充else分支清空图片框。
如果要实现“ID>905时弹出提示,程序继续运行”的需求,应该用MessageBox提示而非抛出异常(抛出异常会中断方法执行),示例调整:
else if (ID > 905) { MessageBox.Show("存档可能损坏,ID超出有效范围(1-905)"); ID = 0; // 清空图片框 pictureBoxSlot1Portrait.Image = null; pictureBoxSlot1Icon.Image = null; } else { // 处理ID=0的情况 pictureBoxSlot1Portrait.Image = null; pictureBoxSlot1Icon.Image = null; }
另外,资源名称拼接可以简化,用ID.ToString("D3")自动补前导零,减少冗余if分支:
string idStr = ID.ToString("D3"); // ID=5→"005",ID=50→"050",ID=123→"123" pictureBoxSlot1Portrait.Image = (Image)Properties.Resources.ResourceManager.GetObject(idStr); pictureBoxSlot1Icon.Image = (Image)Properties.Resources.ResourceManager.GetObject("icon" + idStr);
内容的提问来源于stack exchange,提问作者Maq
相关产品推荐
相关产品推荐

