C#: 查找所有空的catch块

20

我正在审核一些代码。

我发现了一些空的 catch 块。这不是一个好主意,因为有时候程序无法工作,你也无法知道原因。

是否有一种简单的方法可以找到解决方案中所有空的 try catch 块?


1
只是提醒一下 - 并不是所有的空 catch 块都是坏的。有时,开发人员捕获特定的异常,以便可以忽略该异常。 - Matt Hamsmith
1
@Matt,谢谢,我同意你的观点,但我们有一个规则,开发人员必须添加注释以确认其意图。 - Shiraz Bhaiji
@Matt - 但是 catch(Exception) 几乎总是不好的。 - TrueWill
3
你能否在这里发布你的变体?我也对这个话题很感兴趣,但不是正则表达式;-) - Tokk
还有一点需要注意的是 - 有时候库会允许调用用户函数。空的“Catch”语句是防止这些用户提供的函数抛出任何异常并终止库中剩余进程的唯一方法。 - Quark Soup
10个回答

26

使用全局查找对话框,打开正则表达式并搜索:

catch:b*\([^)]*\):b*\{:b*\}

FxCop或ReSharper仅针对空的try/catch而言有点过度,想得很好! - jrummell
4
以上答案对我没有用,但这个可以: "catch((.Exception.)):Wh{:Wh*}"(不带引号)。 - UnhandledExcepSean
是的,这个答案实际上并不符合空catches... @Ghost的工作。 - Dan
答案只有在catch块中没有任何内容时才有效,但是如果catch块仅包含注释掉的代码呢? - Sercan
1
正则表达式在我这里不起作用,除非我将 :b 替换为 \s。(VS 2017) - Marcel

15

扩展了接受的答案以满足下面描述的所有条件。 更新适用于 Visual Studio 2017/2019,适用于 C# 和 C++。

使用查找对话框(CTRL+SHIFT+F),打开正则表达式并搜索:

^(?!\/\/|\/\*).*catch\s*(?:\([^)]*\))*\s*\{\s*(?:(?:\/\/|\/\*).*(\*\/)?\s*)*\}

匹配项:

catch {}
catch{}
catch{
}
catch 
{}
catch () {}
catch (...) {}
catch (int x) {}
catch (Exception x) {}
catch (Exception ex){
}
catch(...){
}
} catch (...){
/**/
}
} catch (...){
/**/
///
}
} catch (...){
//
//
/**/
}
catch (...)
{}
catch(...) { //single line
}
catch(...) { 
//single line}
catch(...) { 
//single line
}
catch(...) { /*multiline*/
}
catch(...) {
 /*multiline*/}
catch(...) {
 /*multiline*/
}
catch (...){ // int i = 0; }

不匹配:

// catch () {}
/* catch () {} */
catch (...){ int i = 0;}
catch (...){ 
int i = 0;}
catch (...){int i = 0;
}
catch (...){ 
// Comment
int i = 0;}
catch (...){ int i = 0; // Comment}

表达式格式错误,至少在 VS 2017 中。 - jjxtra
1
感谢@jjxtra,我已经更新了答案以适用于更现代的VS版本。同时详细说明了它匹配/不匹配的条件。 - Sverrir Sigmundarson
这真是太好了,大多数人都不愿意花时间。 - jjxtra

7

FxCop将会发现许多其他潜在问题,包括这些。


3
你能说出捕获空 catch 块的规则名称吗? - slolife

6

你有ReSharper吗?它可以突出显示代码中发现的问题。


我还没有在ReSharper中找到这个功能的位置或方法...你会怎么做呢? - yeyeyerman
它在ReSharper中显示为警告,但我认为您必须打开代码文件才能看到它。 - jrummell
有趣的是,前几天我在一些代码中发现了其中一个。我们同时使用FxCop和ReSharper;有人明确地抑制了FxCop警告(因此它不会出现在持续集成构建中),并忽略了ReSharper警告。对此你无能为力。 :P - TrueWill
1
关于在构建中找到它们 - 是的,有明确抑制它们的方法,但最好有非常充分的理由这样做。不过,如果没有进行详细的代码审查,很难找到它们。我正在进行这样的审查,并且使用Sverrir的正则表达式来找到这些人是一个很大的帮助! - David T. Macknet

2
这是一个正则表达式,它可以找到仅包含注释的catch块:
catch:b*\([^)]*\)[:b\n]*\{([:b\n]|(\/\*[^*]*\*\/)|(//[^\n]*))*\}

2

感谢Stefan提供的正则表达式建议。我发现建议的正则表达式无法找到没有指定异常的catch块,例如:

catch { }

我稍微修改了Stefan的代码,使异常括号可选:

catch:b*(\([^)]*\))*:b*\{:b*\}

1

按下Ctrl + Shift + F。 展开查找选项。 勾选使用正则表达式 粘贴此正则表达式。

catch\s*(\(\s*Exception(\s*\w+)?\))?\s*\{\s*\}

1
我添加了细节来回答。 - bobah75

1
扩展@bobah75的回答,它无法识别这一行。
catch (System.Data.Entity.Core.EntityException ex)
{
}

所以为了解决这个问题,这里是解决方案。
catch\s*(\(?.+Exception(\s*\w+)?\))?\s*\{\s*([:b\n]|(\/\*[^*]*\*\/)|(//[^\n]*))*\}

你可以在这里测试它。

0
如果可以的话,我建议使用Sonar Analyzer。您可以通过Visual Studio中的NuGet管理器添加它。
它将显示所有未使用的catch块,并向您展示如何处理它的提示,例如:“实现或注释为空的原因”。
此外,它还会显示更多可能存在的代码问题。

0

catch\s*((?.+Exception(\s*\w+)?))?\s*{\s*([:b\n]|(/*[^]*/)|(//[^\n]))}

Visual Studio 2022。只有这个表达式实际上是有效的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接