Debug.Assert并不总是在c#中工作

cod*_*ave 1 .net c# assert visual-studio-2012

我有一个奇怪的问题,Asserts被忽略了.您可以使用此最小示例重现它.我想知道为什么会出现这个问题以及如何面对它:

public class TestAssert
{
    public string EmptyString
    {
        get
        {
            System.Diagnostics.Debug.Assert(false);
            return string.Empty;
        }
    }
    Dictionary<string, object> dict = new Dictionary<string, object>();

    public void ShowAssertIgnored()
    {
        var foo = dict[EmptyString];
    }
}    
Run Code Online (Sandbox Code Playgroud)

Debug.Assert(false)即使评估了属性,您也可以看到它被忽略.打电话吧

var test = new TestAssert();
test.ShowAssertIgnored();
Run Code Online (Sandbox Code Playgroud)

你应该看到我的意思(也显示在图像上).不评估Debug.Assert,但属性是

代码编译并在Debug中运行(其他断言工作正常!),32位,x86 + AnyCPU,VS2012专业,.Net Framework 4

编辑: 该项目是一个控制台应用程序,我连续几次运行它.在System.Diagnostics.Debug.Assert(false);最常见的断点之前会出现一个消息框.但并非总是如此:当我只是多次重试相同的情况时,我有时会在控制台中看到结果.

再说一遍:我可以在VS2012调试器中重现非确定性行为!

spe*_*der 6

如果你阅读了文档,你会发现它Debug.Assert不是为了抛出而设计的.

通常,Assert(布尔)方法用于在程序开发期间识别逻辑错误.断言评估条件.如果结果为false,则会向Listeners集合发送失败消息.您可以通过向Listeners集合添加TraceListener或从中删除一个来自定义此行为.

当应用程序在用户界面模式下运行时,它会显示一个消息框,显示包含文件和行号的调用堆栈.消息框包含三个按钮:Abort,Retry和Ignore.单击"中止"按钮将终止应用程序.如果应用程序在调试器中运行,则单击"重试"会将您发送到调试器中的代码,如果不是,则提供打开调试器.单击忽略继续执行代码中的下一条指令.

如果在UI环境中运行,它可能会触发UI环境/测试运行器设置的侦听器中定义的类似投掷的行为.

所以,简而言之,Debug.Assert(false)不会停止你的应用程序,但它的听众可能会.

假设这里没有UI ...如果您希望代码失败,那么您需要编写自己的TraceListener:

public class MyTraceListener : TraceListener
{
    public override void Write(string msg)
    {
        throw new Exception(msg);
    }
    public override void WriteLine(string msg)
    {
        throw new Exception(msg);
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其添加到侦听器集合:

Debug.Listeners.Add(new MyTraceListener());
Run Code Online (Sandbox Code Playgroud)