1

我有以下代码:

       try
       {
           retval = axNTLXRemote.IsUnitPresent(_servers[0].IPAddress, 1, _servers[0].RemotePort, _servers[0].CommFailDelay * 1000);
       }
       catch (COMException ce)
       {
            throw ce;
       }

这给了我想要摆脱的以下警告:

CA2200 : Microsoft.Usage : 'Connect()' 重新抛出捕获的异常并将其明确指定为参数。改为使用不带参数的“抛出”,以保留最初引发异常的堆栈位置。

我已阅读以下内容try/catch/throw 和 try/catch(e)/throw e 之间的区别,并且我理解 'throw ce; 将重置堆栈跟踪并使其看起来好像从该函数引发了异常。

我想简单地将其更改为“throw”而不是“throw ce”,这将消除警告。

  1. 以下捕获有什么区别:

       catch (COMException ce)
       {
            throw;
       }
    

       catch (COMException)
       {
            throw;
       }
    
  2. 如果我希望以某种方式使用 ce 变量,我是否只需要拥有“COMException ce”?

  3. 另外,当我执行“throw”或“throw ce”时,是调用函数处理还是捕获它?我对此有点不清楚。

4

3 回答 3

1

两种情况都没有区别,但只有当异常变量应该用于堆栈/消息等时。

所以:

catch(ComException);

catch(ComException ex);

语句将产生类似的 MSIL,除了 ComException 对象的局部变量:

.locals init ([0] class [mscorlib]System.Exception ex)
于 2013-06-06T14:14:57.037 回答
1

我敢肯定,有人会加入一个超级技术的答案,但根据我的经验,你的前两个问题的答案是没有区别,正如你所说,只有ce当你打算用它来写作时,你才会包括在内堆栈跟踪到日志或向用户显示消息或类似内容。

throw会将异常发送到链上。这可能是调用方法,或者,如果您的方法有多个嵌套的 try/catch 块,它会将异常发送到当前 try/catch 块嵌套在其中的下一个 try/catch 块。

如果您想进一步阅读该主题,这里有几个很好的资源可以查看:

于 2013-06-06T14:18:12.853 回答
1
  1. 唯一的区别是,使用 时catch (COMException ce),您将异常分配给变量,从而允许您在catch块内访问它。除此之外,它在各方面都是相同的。
  2. 我不确定这里的问题是什么。如果要访问异常对象,必须在catch子句中给它一个变量名。
  3. 无论以何种方式或在何处引发异常,异常都会通过调用堆栈冒泡到最近catch的匹配块。

这是一个例子。

void Method1()
{
    try
    {
        Method2();
    }
    catch // this will catch *any* exception
    {
    }
}

void Method2()
{
    try
    {
        Method3();
    }
    catch (COMException ex) // this will catch only COMExceptions and exceptions that derive from COMException
    {
    }
}

void Method3()
{
    // if this code were here, it would be caught in Method2
    throw new COMException();


    // if this code were here, it would be caught in Method1
    throw new ApplicationException();
}
于 2013-06-06T14:21:36.993 回答