C# WPF应用中Try-Catch块未捕获方法调用异常问题排查
问题根本原因
List<T>.Find(Predicate<T>)无匹配结果时只会返回null,不会抛出任何异常,你原本预期「搜索无匹配时触发异常」的逻辑本身不成立。- 你将Find返回的
null直接传入ShowRecord()方法,方法内部直接访问game.GameName等成员时触发NullReferenceException,但你的try-catch仅捕获ArgumentNullException,两种异常类型不匹配,自然无法捕获。 - 调试时通用
Exceptioncatch块断点未触发,通常是Visual Studio默认开启了「仅我的代码」调试选项,且NullReferenceException被设置为遇到即中断,会优先停在异常抛出的代码行,继续执行就会进入catch块。
修复方案
不要依赖异常处理判断搜索结果,提前判断Find返回值是否为null即可,修改搜索按钮点击逻辑如下:
private void searchButton_Click(object sender, RoutedEventArgs e) { var result = gameLibrary.Find(x => x.GameName == searchBox.Text); if (result == null) { string term = searchBox.Text; searchBox.Text = $"'{term}' 未在库中找到,请尝试其他搜索词。"; return; } ShowRecord(result); }
如果需要加兜底逻辑避免其他未知异常导致崩溃,可以补充通用异常捕获:
private void searchButton_Click(object sender, RoutedEventArgs e) { try { var result = gameLibrary.Find(x => x.GameName == searchBox.Text); if (result == null) { string term = searchBox.Text; searchBox.Text = $"'{term}' 未在库中找到,请尝试其他搜索词。"; return; } ShowRecord(result); } catch (Exception ex) { // 此处可新增日志记录异常详情 searchBox.Text = "搜索时发生未知错误,请重试。"; } }
可选优化
可以给ShowRecord方法增加参数非空校验,避免其他调用方误传null导致崩溃:
public void ShowRecord(Game game) { if (game == null) throw new ArgumentNullException(nameof(game), "不能显示空的游戏记录"); // 原有逻辑保持不变 titleBlock.Text = game.GameName; systemBlock.Text = game.GameSystem; formatBlock.Text = game.GameFormat; completedBlock.Text = game.IsComplete.ToYesNo(); totalledBlock.Text = game.IsTotaled.ToYesNo(); gamepassBlock.Text = game.GamePassStatus; installedBlock.Text = game.IsInstalled.ToYesNo(); recordNumber.Content = (gameLibrary.FindIndex(x => x == game) + 1).ToString(); recordCount.Content = gameLibrary.Count; }
内容的提问来源于stack exchange,提问作者Keven M
相关产品推荐
相关产品推荐

