VS2017中使用iText7 .Net的RegexBasedLocationExtractionStrategy遇Nullable异常求助
遇到这种Nullable异常别慌,我之前处理过类似的问题,结合你用的是iText7的RegexBasedLocationExtractionStrategy,而且代码来自官方测试用例,大概率是你的目标PDF结构和测试用例的标准PDF不一致,或者API的可空类型处理没做好。下面给你几个具体的排查和解决方向:
1. 先过滤集合中的空项和无效位置
官方测试用例的PDF通常是结构规范的,但你实际处理的PDF可能存在文本块位置信息缺失(比如扫描后OCR的PDF、生成时元数据不完整的PDF),导致GetResultantLocations()返回的集合里有null或者属性未初始化的对象。
你可以在foreach循环前先做一层过滤:
var allLocations = strategy.GetResultantLocations(); // 过滤掉null项,同时确保位置矩形不为空 var validLocations = allLocations?.Where(loc => loc != null && loc.GetRectangle() != null) ?? Enumerable.Empty<IExtractionResult>(); foreach (var location in validLocations) { // 你的业务逻辑 }
2. 检查正则匹配结果是否为空
如果你的正则表达式没有匹配到任何文本内容,GetResultantLocations()可能返回一个包含未初始化对象的集合,这时候访问它的属性就会触发Nullable异常。
建议先判断集合是否有效再进入循环:
var locations = strategy.GetResultantLocations(); if (locations == null || !locations.Any()) { Console.WriteLine("没有匹配到任何文本位置"); return; } foreach (var location in locations) { // 访问属性前先做null检查,比如获取矩形位置 var rect = location?.GetRectangle(); if (rect == null) { continue; // 跳过无效的位置项 } // 处理rect的X/Y/Width/Height等属性 }
3. 核对iText7版本与测试用例的一致性
你安装的iText7 NuGet包版本可能和官方测试源码对应的版本不匹配,新版本的API可能把某些返回值改成了可空类型,而旧的测试代码没有处理null的情况。
解决办法:
- 查看测试源码的版本(比如对应仓库分支),然后把你的NuGet包版本调整到一致;
- 如果不想改版本,就按照当前版本的API文档,给所有可能返回null的属性加上null防护。
4. 调试定位具体的异常源
最直接的方式是用VS的调试功能:在foreach行设置断点,当异常触发时,查看location对象的各个属性(比如GetRectangle()、GetText()),看哪个属性是null导致的异常。
比如如果是访问location.GetRectangle().X时抛出异常,那就是GetRectangle()返回了null,这时候在代码里先判断rect != null再访问其成员即可。
内容的提问来源于stack exchange,提问作者D_Carroll

