C# List<char>获取指定字符:解决char转int引发的ArgumentOutOfRangeException
问题核心根源
你触发越界异常的本质是搞混了集合元素值匹配和索引位置取值两套完全独立的逻辑:
List<T>的索引器只接受从0开始的整数位置作为入参,这个值代表元素在列表里的排列顺序,和列表存的元素本身是什么没有绑定关系。- C#里
char是内置值类型,本身支持隐式转换为对应Unicode码点的整数(比如'?'对应的整数值是63)。所以你写pc['?']的时候,编译器不会把这个字符当成“要匹配的目标值”,反而会自动把字符转成整数63,尝试取列表第63个位置的元素——而你的列表一共只存了3个元素,合法索引只有0、1、2,自然会抛出越界异常。 - 你之前用string类型的List时没遇到这个问题,是因为string没法隐式转成int当索引,编译器会直接报错提醒你逻辑有问题;但char和int的隐式转换是C#内置的,编译器不会拦截,才容易出现这种“看着写的对,实际跑不通”的逻辑坑。
正确实现方案
场景1:适配你现有代码逻辑的最简修正
你当前列表里的元素本身就是你要返回的目标字符,根本不需要在判断存在后再从列表里取值——只要Contains判断为真,你传入的待匹配字符本身就是你要返回的内容,直接转成string即可:
List<char> pc = new List<char>(); pc.Add('?'); pc.Add(';'); pc.Add(','); char targetChar = Convert.ToChar(temp); return pc.Contains(targetChar) ? targetChar.ToString() : null;
场景2:通用匹配取值(适配后续业务扩展)
如果后续业务调整,列表存储的内容需要和入参做匹配、再返回列表中存储的匹配元素(而非入参本身),可以用LINQ提供的集合匹配方法,从根源避免手动写索引逻辑的坑:
- 首先引入必要的命名空间:
using System.Linq; - 调用
FirstOrDefault方法遍历列表匹配目标值:
char targetChar = Convert.ToChar(temp); // 遍历列表找到第一个和目标字符相等的元素,找不到则返回char类型的默认值'\0' char matchedItem = pc.FirstOrDefault(item => item == targetChar); // 判断是否匹配成功,匹配到则返回字符串,否则返回null return matchedItem != default(char) ? matchedItem.ToString() : null;
这个方法是通过遍历元素做值匹配,全程不会把char值当成索引用,完全不存在隐式转换导致的越界问题。
避坑提醒
不要因为列表存储的元素类型是char,就直接把char值传给索引器当位置参数——只要是用索引器,传入的参数永远是元素在列表中的位置序号,和元素本身的值无关。
内容的提问来源于stack exchange,提问作者Burair abbas
相关产品推荐
相关产品推荐

