WPF导入大CSV文件时出现System.IndexOutOfRangeException错误求助
解决CSV导入WPF应用时的System.IndexOutOfRangeException错误
你的问题出在手动分割CSV行时,部分行的字段数量不足16个,导致访问split[15]这类索引时超出数组范围。常见的诱因包括空行、缺失字段、或者字段内容里包含未转义的分号;。下面是具体的解决步骤:
1. 先过滤无效行并验证字段数量
在解析前先筛掉空行,同时检查分割后的数组长度是否符合预期,避免直接访问索引导致崩溃:
public static List<Cloths> ReadFile(string filepath) { var lines = File.ReadAllLines(filepath); var data = from l in lines.Skip(1) where !string.IsNullOrWhiteSpace(l) // 跳过空行 let split = l.Split(';') where split.Length == 16 // 只处理列数正确的行 select new Cloths { Hauptartikelnr = split[0], Artikelname = split[1], Hersteller = split[2], Beschreibung = split[3], Materialangaben = split[4], Geschlecht = (Gender)Enum.Parse(typeof(Gender), split[5]), Produktart = split[6], Aermel = split[7], Bein = split[8], Kragen = split[9], Herstellung = split[10], Taschenart = split[11], Grammatur = split[12], Material = split[13], Ursprungsland = split[14], Bildname = split[15] }; return data.ToList(); }
2. 安全处理枚举解析
直接用Enum.Parse如果遇到CSV里的性别值和枚举不匹配(比如大小写错误、拼写失误),也会抛出异常。换成Enum.TryParse来做安全解析:
Geschlecht = Enum.TryParse(split[5], out Gender parsedGender) ? parsedGender : Gender.Herren,
这里给了一个默认值Gender.Herren,你可以根据需求调整成其他默认值或者抛出自定义异常。
3. 用专业CSV库规避边缘情况
如果你的CSV字段里可能包含分号(比如描述字段里的100% Baumwolle; maschinenwaschbar),手动Split(';')会把这类字段拆成两个元素,直接导致列数错误。这种情况下,推荐使用CsvHelper(可以通过NuGet安装),它能自动处理带引号的特殊字段,还能自动映射实体类:
CsvHelper实现示例:
using CsvHelper; using System.Globalization; using System.IO; public static List<Cloths> ReadFile(string filepath) { using var streamReader = new StreamReader(filepath); using var csvReader = new CsvReader(streamReader, CultureInfo.InvariantCulture); csvReader.Configuration.Delimiter = ";"; // 指定CSV分隔符 // 如果你的实体类属性名和CSV表头完全一致,下面两行可以省略 csvReader.Configuration.HeaderValidated = null; csvReader.Configuration.MissingFieldFound = null; return csvReader.GetRecords<Cloths>().ToList(); }
用这个库不仅能解决分号转义的问题,还能自动处理枚举映射、空值等情况,比手动写split靠谱得多。
4. 定位具体出错的行
如果想快速找到哪个行出了问题,可以改成循环遍历的方式,添加调试输出:
public static List<Cloths> ReadFile(string filepath) { var clothList = new List<Cloths>(); var lines = File.ReadAllLines(filepath); for (int i = 1; i < lines.Length; i++) { // 从第2行开始(跳过表头) var line = lines[i]; if (string.IsNullOrWhiteSpace(line)) continue; var split = line.Split(';'); if (split.Length != 16) { // 输出错误行的行号和内容,方便排查 System.Diagnostics.Debug.WriteLine($"错误行(行号:{i+1}):{line}"); continue; } // 解析并添加到列表 clothList.Add(new Cloths { Hauptartikelnr = split[0], Artikelname = split[1], // ... 其他属性赋值 Bildname = split[15] }); } return clothList; }
内容的提问来源于stack exchange,提问作者Arror404
相关产品推荐
相关产品推荐

