考虑这种方法(请原谅 Chuck Norris 幽默的可悲尝试 :)):
public class ChuckNorrisException : Exception
{
public ChuckNorrisException()
{
}
public ChuckNorrisException(string message)
: base(message)
{
}
public ChuckNorrisException(string message, Exception cause)
: base(message, cause)
{
}
protected ChuckNorrisException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
static void ExceptionTest(double x)
{
try
{
double y = 10 / x;
Console.WriteLine("quotient = " + y);
}
catch (Exception e)
{
e = e is DivideByZeroException ? new ChuckNorrisException("Only Chuck Norris can divide by 0!", e) :
e;
throw e;
}
}
在 resharper 中,我在“throw e”行上收到一条警告,提示“Exception rethrow possibly intended”。但显然在这种情况下,这不是本意,因为 e 可以包装在 ChuckNorrisException 中,如果我只使用“throw”,则不会抛出包装的异常。
我知道我可以抑制 resharper 警告,但如果我没记错的话,所有 情况下它将被关闭。我只是想知道是否还有其他人遇到过这种情况。我发现的唯一解决方法是创建另一个异常变量(例如 e2),然后将其抛出。这可能是我在这里能做的最好的了。似乎 resharper 可以检测到这个问题,并且足够聪明地知道如果 e 被修改,那么抛出 e 就可以了。
谢谢。
[编辑] 对不起,我忘记了一步。在抛出之前,我需要记录异常,所以我不能只做:
e = e is DivideByZeroException ? new ChuckNorrisException("Only Chuck Norris can divide by 0!", e) :
e;
throw e;
我必须做的:
e = e is DivideByZeroException ? new ChuckNorrisException("Only Chuck Norris can divide by 0!", e) :
e;
LogException(e);
throw e;
最佳答案
也许我没理解这个问题,所以如果我说错了,请纠正我。
这里有两种情况:
首先是你捕获了 原始异常。然后你包装 它在一个新的异常实例中作为 内部异常,然后抛出 新的一个。在这种情况下不会丢失任何信息(内部异常会保留所有信息),因此不会发出警告。
第二个是你捕获并 重新抛出原来的异常。如果你重新 throw ,你 不应该使用“throw e”,因为它 将篡改堆栈跟踪。 这就是 ReSharper 打印一个 警告。要重新抛出捕获的异常,您应该单独使用“throw”关键字。
this question 的答案比我能更好地解释它。由于微妙的副作用和大量的人弄错了这个细节,我个人认为 re-throw 语法是有缺陷的。
无论如何,这是对您收到警告的原因的描述。这是我会做的:
catch(DivideByZeroException e)
{
// we don't catch any other exceptions because we weren't
// logging them or doing anything with the exception before re-throwing
throw new ChuckNorrisException("Useful information", e);
}
*编辑——如果您需要记录异常,您可以改为执行类似的操作。注意:这是我的首选解决方案,因为我认为它比自己查询异常类型更易读并且包含错误的可能性更小:
// catch most specific exception type first
catch(DivideByZeroException e)
{
Log(e);
throw new ChuckNorrisException("Useful information", e);
}
catch(Exception e) // log & re-throw all other exceptions
{
Log(e);
throw; // notice this is *not* "throw e"; this preserves the stack trace
}
另一种选择是:
catch(Exception e)
{
Log(e);
if(e is DivideByZeroException)
{
// wrap + throw the exception with our new exception type
throw new ChuckNorrisException("useful info", e);
}
// re-throw the original, preserving the stack trace
throw;
}
关于c# - 可能有意重新抛出 Resharper 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1776600/