这是重现我期望得到的行为的代码:
static void Main(string[] args)
{
// try // #2
{
string x = null; // #1
AssertNotNull(x, nameof(x));
}
// catch (ArgumentNullException) { } // #2
Console.WriteLine("Passed.");
Console.ReadKey();
}
[DebuggerHidden]
public static void AssertNotNull<T>(T arg, string argName) where T : class
{
if (arg == null)
throw new ArgumentNullException(argName);
}
从 VS2008 开始的任何 VS 的行为都是相同的(没有检查早期版本)。
如果您在调试(使用标准调试设置)下运行它,则在您修复代码(使用 EnC)之前不允许继续。由于 [DebuggerHidden]
和“Unwind stack on unhandled exception”设置组合(设置默认启用),按 F5 只会重新运行断言。
要修复代码,只需将 #1 行替换为 object x = ""
,将下一条语句设置为它并再次按 F5。
现在,为 ArgumentNullException 启用“抛出时中断”并取消注释标有 #2 的行。 行为发生变化:您再次停止断言,但堆栈不会展开(很容易通过 CallStack 窗口进行检查)。 F5 将从抛出异常的地方继续。
好的,那么……现在的问题是: 有什么方法可以在中断已处理 异常时启用自动堆栈展开?
隐藏的 VS 选项、现有扩展或(可能)可以从我自己的扩展中使用的 API?
UPD:为了澄清这个问题:我想在断言失败的那一行中断,用 edit 编辑代码并继续,将下一条语句设置为固定代码并继续执行。
如果异常没有被捕获到堆栈中,它就会工作。
UPD2 由 Hans Passant 提议:发布 an suggestion on UserVoice .欢迎投票:)
最佳答案
and uncomment the lines marked with #2
这是您问题的关键部分。你改变了不止一件事,关键的改变是你改变了堆栈展开的方式。您喜欢的调试器选项标题为“Unwind stack on unhandled exception”。问题是,不再有未处理的异常。您的 catch 子句会处理它,现在是 CLR 展开堆栈。
而且必须是 CLR 执行展开,调试器没有选项在您要求的第一次异常中断时执行此操作。而 SetNext 在这一点上无法工作。如果我正确地解释了这个问题,你真的很想拥有,因为你接下来需要做的是忙碌的工作,单步执行 catch block 并不是什么大事。
虽然它没有实现,但我认为它在技术上是可行的。但只是因为我很幸运地不知道调试器团队需要做多少工作。让E+C更好地工作是一个很好的要求,你可以propose it here .将您的提案的 URL 作为评论发布,很有可能获得大量选票。我会投赞成票。
关于c# - Visual Studio : edit-and-continue on handled exceptions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36220126/