这是一个重现我期望获得的行为的代码:
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)之前不允许继续。点击F5将重新运行由于[DebuggerHidden]
和“未处理异常时展开堆栈”设置组合的断言(默认情况下启用设置)。
要修复代码,只需将#1行替换为object x = ""
,将下一个语句设置为它并再次点击F5。
现在,为ArgumentNullException启用“thrown thrown”并取消注释标记为#2的行。 行为改变:你再次断言断言,但堆栈没有解除(很容易用CallStack窗口检查)。 F5将从抛出异常的地方继续。
好的,所以...现在的问题是: 在打破已处理的例外时,有没有办法启用自动堆栈展开?
隐藏VS选项,现有扩展程序或(可能)API可以在我自己的扩展程序中使用吗?
UPD:澄清问题:我想在断言失败的行中断,用编辑编辑代码并继续,将next语句设置为固定代码并继续执行。
如果异常没有在堆栈中被捕获,它就可以正常工作。
UPD2 正如Hans Passant所建议的:张贴an suggestion on UserVoice。随意投票:)
答案 0 :(得分:3)
并取消注释标有#2
的行
这是您问题的关键部分。你改变了不止一件事,关键的变化是你改变了堆栈展开的方式。您喜欢的调试器选项名为&#34;在未处理的异常&#34;上展开堆栈。问题是,再也没有未处理的例外。你的catch子句处理它,它现在是解开堆栈的CLR。
它必须是进行展开的CLR,调试器没有选择在您要求的第一次机会异常中断时执行此操作。并且SetNext在那时无法工作。其中,如果我正确地解释了这个问题,那么你真的希望自己接下来需要做的就是忙碌的工作,单步进入catch块并不是一件巨大的快乐。
虽然没有实现,但我认为它在技术上是可行的。但这只是因为我没有意识到调试器团队必须做多少工作。要让E + C更好地工作是个好问题,你可以propose it here。将URL作为常规发布到您的提案中,并且很有可能获得一堆投票。我会投票支持它。
答案 1 :(得分:2)
澄清问题:我想在失败的情况下突破 断言,用编辑编辑代码并继续,将next语句设置为 固定代码并继续执行。
只要抛出System.ArgumentNullException
,它就会中断,无论它是否会被catch
块捕获。
然而,you cannot edit and continue active statements。如果您尝试修改断言行,您会看到类似这样的内容: