DataGridView角色对比删除异常求助:未匹配时触发索引错误
问题描述
我用C#写代码对比两个DataGridView(DGV)的角色列:
- DGV1是包含重复角色的原始数据
- DGV4是无重复的角色字典表
需求是遍历字典表的每一行,若角色在DGV1中存在,就从字典表删除该行,最终只保留DGV1里没用到的角色。当前代码能删除匹配的角色,但如果字典表有DGV1没有的角色,会因为DGV1循环越界导致索引错误。另外备注:字典表行删除后会自动移到首个索引,不用递增变量i。
现有代码:
int eliminado = 0; int filasDGV1 = dataGridView1.Rows.Count; int filasDGV4 = dataGridView4.Rows.Count; int i = 0; int j = 0; do { string perfilVacio = dataGridView4["GRANTED_ROLE", i].Value.ToString(); string perfiles = dataGridView1["GRANTED_ROLE", j].Value.ToString(); if(perfiles != perfilVacio) { j++; } else if(perfiles == perfilVacio) { dataGridView4.Rows.RemoveAt(i); } } while (eliminado <= filasDGV4);
问题根源
j会持续递增直到超出DGV1的行索引范围,直接触发索引越界错误eliminado变量从未更新,循环终止条件无效,要么无限循环要么报错- 逐行对比的方式效率低,还容易出现逻辑漏洞
解决方案
换个思路:先把DGV1里的所有角色提取到一个集合中(集合查找速度快),再遍历DGV4直接判断角色是否存在,存在就删除。
优化后的代码:
// 提取DGV1中所有有效角色到HashSet,去重且查找效率高 HashSet<string> usedRoles = new HashSet<string>(); foreach (DataGridViewRow row in dataGridView1.Rows) { // 跳过新行和空值,避免空引用 if (!row.IsNewRow && row.Cells["GRANTED_ROLE"].Value != null) { string role = row.Cells["GRANTED_ROLE"].Value.ToString().Trim(); usedRoles.Add(role); } } // 遍历DGV4处理删除逻辑 int i = 0; while (i < dataGridView4.Rows.Count) { DataGridViewRow currentRow = dataGridView4.Rows[i]; if (!currentRow.IsNewRow && currentRow.Cells["GRANTED_ROLE"].Value != null) { string role = currentRow.Cells["GRANTED_ROLE"].Value.ToString().Trim(); if (usedRoles.Contains(role)) { // 角色存在则删除,删除后下一行自动移到当前索引,所以i不递增 dataGridView4.Rows.RemoveAt(i); } else { // 角色不存在,检查下一行 i++; } } else { // 空行或空值,直接跳过 i++; } }
代码说明
- 用
HashSet存储DGV1的角色,查找时间复杂度为O(1),避免了逐行对比的低效和越界问题 - 遍历DGV4时,删除行后不递增
i(符合你说的删除后行自动移到当前索引的特性),未匹配则正常递增 - 增加了空行和空值判断,避免运行时出现空引用异常
内容的提问来源于stack exchange,提问作者Rafael Suazo
相关产品推荐
相关产品推荐

