我有一段看起来像这样的代码:
try
{
classVar = functionCall(input, sEnum.First);
classVar = functionCall(input, sEnum.Second);
classVar = functionCall(input, sEnum.Third);
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
然而,我的异常剂量显示它来自哪个特定的电话。堆栈跟踪也只显示来自函数调用内部调用的另一个类的详细信息。
包装它的另一种方法是:
try
{
classVar = functionCall(input, sEnum.First);
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
try
{
classVar = functionCall(input, sEnum.Second);
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
try
{
classVar = functionCall(input, sEnum.Thrid);
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
虽然我认为它的可读性远低于以前的版本。
是否有一种模式用于包装函数调用或以某种方式传递异常,以便稍后可以看到它们来自哪里,同时保持代码可读?
答案 0 :(得分:4)
您可能想要做的是捕获并显示异常堆栈跟踪以及异常的字符串值。
您可以通过在异常上使用StackTrace属性来完成此操作。这将让您看到发生异常的位置。
catch (Exception e) {
Console.WriteLine(e.StackTrace);
}
如何打印它的示例。我相信你可以弄清楚如何将它与调试系统集成。
答案 1 :(得分:2)
在functioncall()方法和debug.assert中添加try / catch。如果你绝对需要,可以在那里重新抛出异常,将链传递给这段代码。
答案 2 :(得分:2)
堆栈跟踪中的行号将告诉您三个中的哪一个被调用。
答案 3 :(得分:1)
如何编写自己的异常类,作为其有效负载的一部分携带枚举值?您还可以编写日志消息以使其更具描述性,这样您就不必依赖堆栈跟踪作为唯一的信息来源。
答案 4 :(得分:1)
选项1
更改functionCall()
以使用上下文信息重新抛出自定义异常。在更高级别捕获异常以进行日志记录,调用Debug.Assert
等
选项2 这种模式可以在可读性略有损失的情况下提供异常处理逻辑的重用。注意:以清晰为代价过度使用委托技术可能会成为代码味道。
static void InvokeActionWithContext(Action action, string description) {
try
{
action();
}
catch(Exception ex)
{
throw new AnExceptionWithContext(description, ex);
}
}
// call like this
InvokeActionWithContext(
() => classVar = functionCall(input, sEnum.Third),
"Initializing value three"
);
答案 5 :(得分:0)
虽然它可能不是最优雅的解决方案,但您可以添加另一个变量来跟踪您所处的步骤:
int step = 0;
try
{
classVar = functionCall(input, sEnum.First);
step++;
classVar = functionCall(input, sEnum.Second);
step++;
classVar = functionCall(input, sEnum.Third);
}
catch (Exception ex)
{
//examine the step variable here
Debug.Assert(false, ex.ToString());
}
答案 6 :(得分:-1)
这有点幼稚,但......
ExceptHandler<sEnum> h = new ExceptHandler<sEnum>();
try
{
h.Step = sEnum.First;
classVar = functionCall(input, sEnum.First);
h.Step = sEnum.Second;
classVar = functionCall(input, sEnum.Second);
h.Step = sEnum.Third;
classVar = functionCall(input, sEnum.Third);
}
catch (Exception ex)
{
h.AssertException(ex.ToString());
}
ExceptHandler基本上是一个状态机,可以保存您正在执行的实际状态。您可以将其定义为基类,并从特定情况继承它...
编辑使其更像.NET:)