有些帖子询问这两者之间的区别是什么.
(为什么我还要提这个...)
但我的问题是不同的,我称之为"抛出前"在另一个错误的神像处理方法.
public class Program {
public static void Main(string[] args) {
try {
// something
} catch (Exception ex) {
HandleException(ex);
}
}
private static void HandleException(Exception ex) {
if (ex is ThreadAbortException) {
// ignore then,
return;
}
if (ex is ArgumentOutOfRangeException) {
// Log then,
throw ex;
}
if (ex is InvalidOperationException) {
// Show message then,
throw ex;
}
// and so on.
}
}
Run Code Online (Sandbox Code Playgroud)
如果try & catch用于Main,那么我会throw; …
我有一个方法可以抛出两个不同的异常,CommuncationException和SystemException.在这两种情况下,我都使用相同的三行代码块.
try {
...
}
catch (CommunicationException ce) {
...
}
catch {SystemExcetion se) {
...
}
Run Code Online (Sandbox Code Playgroud)
有没有可能这样做?
try {
...
}
catch (CommunicationException ce, SystemException se) {
...
}
Run Code Online (Sandbox Code Playgroud)
然后我就不用写这么多代码了.我知道我可以将异常处理提取到私有方法,但由于代码只有3行,因此方法定义将占用比正文本身更多的代码.
我正在进行代码审查,并找到了许多具有以下格式的代码:
public MyResponse MyMethod(string arg)
{
using (Tracer myTracer = new Tracer(Constants.TraceLog))
{
MyResponse abc = new MyResponse();
// Some code
return abc;
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行代码分析时,我得到一个CA2000警告Microsoft.Reliability
应该将代码重写为:
public MyResponse MyMethod(string arg)
{
MyResponse abc = new MyResponse();
using (Tracer myTracer = new Tracer(Constants.TraceLog))
{
// Some code
}
return abc;
}
Run Code Online (Sandbox Code Playgroud)
或者没关系?
编辑
报告警告的行是:
MyResponse abc = new MyResponse();
Run Code Online (Sandbox Code Playgroud)
MyResponse是标准的数据集.
完整的错误消息是:
警告150 CA2000:Microsoft.Reliability:在方法'xxxxx(Guid,Guid)'中,对象'MyResponse'未沿所有异常路径放置.在对所有引用超出范围之前,在对象'MyResponse'上调用System.IDisposable.Dispose.
我读到在catch块中,我可以使用"throw"重新抛出当前异常.或"扔前";
来自:http://msdn.microsoft.com/en-us/library/ms182363%28VS.80%29.aspx
"要保留原始堆栈跟踪信息的异常,请使用throw语句而不指定异常."
但是当我尝试这个时
try{
try{
try{
throw new Exception("test"); // 13
}catch (Exception ex1){
Console.WriteLine(ex1.ToString());
throw; // 16
}
}catch (Exception ex2){
Console.WriteLine(ex2.ToString()); // expected same stack trace
throw ex2; // 20
}
}catch (Exception ex3){
Console.WriteLine(ex3.ToString());
}
Run Code Online (Sandbox Code Playgroud)
我得到三个不同的堆栈.我期待第一个和第二个跟踪是相同的.我究竟做错了什么?(或理解错误?)
System.Exception:在c:\ Program.cs中的ConsoleApplication1.Program.Main(String [] args)上测试:第13行System.Exception:在c:\ Program中的ConsoleApplication1.Program.Main(String [] args)进行测试. cs:第16行System.Exception:在c:\ Program.cs中的ConsoleApplication1.Program.Main(String [] args)进行测试:第20行
正如大家所知,在c#中捕获并重新抛出异常这种方式是邪恶的,因为它会破坏堆栈跟踪:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw ex;
}
Run Code Online (Sandbox Code Playgroud)
在不丢失堆栈跟踪的情况下重新抛出异常的正确方法是:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw;
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是我得到了很多编译警告:"变量'ex'被声明但从未使用过".如果你有很多这些,可能会在垃圾中隐藏一个有用的警告.那就是我做的:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException)
{
throw;
}
catch(AnotherException ex)
{
//handle it
}
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但我想知道重新抛出未设置为变量的异常是否有任何缺点..net如何威胁这个?
提前致谢
编辑: 我已经改变了我的代码,以便更清楚我想做什么,因为有些人误解了