Debug.Assert -s 使用相同的错误消息。我应该将其提升为静态变量吗?

发布于 2024-09-06 01:27:59 字数 1195 浏览 9 评论 0原文

我喜欢断言和代码可读性,但不喜欢代码重复,并且在几个地方我使用 Debug.Assert 来检查相同的条件,如下所示:

Debug.Assert(kosherBaconList.SelectedIndex != -1, "An error message along the lines - you should not ever be able to click on edit button without selecting a kosher bacon first.");

这是对实际错误的响应,尽管实际列表不含犹太培根。无论如何,我可以想到两种方法:

private static readonly mustSelectKosherBaconBeforeEditAssertMessage = 
    "An error message along the lines - you should not ever be able to " +
    "click on edit button without selecting a something first.";
...
Debug.Assert(
    kosherBaconList.SelectedIndex != -1, 
    mustSelectKosherBaconBeforeEditAssertMessage)

或者:

if (kosherBaconList.SelectedIndex == -1)
{
    AssertMustSelectKosherBaconBeforeEdit();
}
...
[Conditional("DEBUG")]
private void AssertMustSelectKosherBaconBeforeEdit()
{
    // Compiler will optimize away this variable.
    string errorMessage = 
        "An error message along the lines - you should not ever be able to " +
        "click on edit button without selecting a something first.";

    Debug.Assert(false, errorMessage);
}

或者是否有第三种方法比上面任何一种方法都少?请分享。 也欢迎一般有用的相关提示。

I love Asserts and code readability but not code duplication, and in several places I use a Debug.Assert which checks for the same condition like so:

Debug.Assert(kosherBaconList.SelectedIndex != -1, "An error message along the lines - you should not ever be able to click on edit button without selecting a kosher bacon first.");

This is in response to an actual bug, although the actual list does not contain kosher bacon. Anyhow, I can think of two approaches:

private static readonly mustSelectKosherBaconBeforeEditAssertMessage = 
    "An error message along the lines - you should not ever be able to " +
    "click on edit button without selecting a something first.";
...
Debug.Assert(
    kosherBaconList.SelectedIndex != -1, 
    mustSelectKosherBaconBeforeEditAssertMessage)

or:

if (kosherBaconList.SelectedIndex == -1)
{
    AssertMustSelectKosherBaconBeforeEdit();
}
...
[Conditional("DEBUG")]
private void AssertMustSelectKosherBaconBeforeEdit()
{
    // Compiler will optimize away this variable.
    string errorMessage = 
        "An error message along the lines - you should not ever be able to " +
        "click on edit button without selecting a something first.";

    Debug.Assert(false, errorMessage);
}

or is there a third way which sucks less than either one above? Please share.
General helpful relevant tips are also welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二货你真萌 2024-09-13 01:27:59

使用第一种(重复)形式。

原因是:

  • 工作量减少了。断言仅用于调试,因此重复不会给发布版本带来任何低效率。当代码已经具有完美的可读性和功能时,不要浪费时间试图使代码“漂亮”或“优雅”。

  • 我认为它实际上比您的替代方案更短、更具可读性并且更容易维护。

  • 当您在调试器中点击断言时,在代码中包含完整消息非常有用,这样您就可以了解断言的含义。很多程序员使用 Assert(kosherBaconList.SelectedIndex != -1);根本没有任何解释,如果你编写了代码,这很好,但是当你点击别人的断言时,你不知道它意味着什么。也就是说,我知道我称你的方法为“错误”,但我到底需要修复什么才能称其为“正确”?因此,断言消息应该指出问题是什么,以及盯着 Assert() 调用的人需要做什么来修复它。当调试器在测试运行中停止时,您希望它就在您面前。

  • 有时您会发现添加与触发断言的上下文相关的附加信息很有用,因此您不必实际调试代码来确定 3 个“相同”断言中哪一个失败了。为此,我经常使用断言文本,例如“BaconManager.Cook:您必须选择...”和“BaconManager.Wrap:您必须选择...”。

  • 如果您在 Assert 调用中包含文本,它将不会被编译到您的发布版本中。但是,一旦将其设为静态变量,您就会在发布版本中包含(未使用的)字符串,从而用调试垃圾堵塞它。

如果您想检查多个条件来测试对象的有效性,则可以使用子例程,即

[Conditional("DEBUG")] 
private void AssertValidity() 
{ 
    Debug.Assert(kosherBaconList.SelectedIndex != -1, "Nothing selected in kosher bacon list"); 
    Debug.Assert(kosherBaconList.COunt > 0, "kosher bacon list is empty!"); 
} 

Use the first (repetitive) form.

The reasons for this are:

  • It's less work. Asserts are debug-only, so the repetition doesn't add any inefficiency to the release build. Don't waste time trying to make code "pretty" or "elegant" when it is already perfectly readable and functional.

  • I'd argue it's actually shorter, more readable, and more easily maintained than your alternatives.

  • When you hit an Assert in your debugger, it's very useful to have the full message in the code so you can see what the assert means. A lot of programmers use Assert(kosherBaconList.SelectedIndex != -1); with no explanation at all, which is fine if you wrote the code, but when you hit someone else's Assert you have no idea what it means. i.e. I know I called your method "wrong", but what the heck do I have to fix to call it "right"? The assert message should therefore indicate what the problem is, and what the person staring at the Assert() call needs to do to fix it. And you want it right there in front of you when your debugger stops in the middle of your test run.

  • Sometimes you'll find it is useful to add additonal information relating to the context in which the assert fired, so you don't have to actually debug the code to work out which of your 3 "identical" asserts failed. I often use assert text like "BaconManager.Cook: You must select..." and "BaconManager.Wrap: You must select..." for this reason.

  • If you include the text in the Assert call, it will not be compiled into your release build. But as soon as you make it a static variable, you will include the (unused) string in your release build, clogging it up with debugging junk.

A subroutine could be used if you want to check more than one condition to test the validity of your object, i.e.

[Conditional("DEBUG")] 
private void AssertValidity() 
{ 
    Debug.Assert(kosherBaconList.SelectedIndex != -1, "Nothing selected in kosher bacon list"); 
    Debug.Assert(kosherBaconList.COunt > 0, "kosher bacon list is empty!"); 
} 
遥远的她 2024-09-13 01:27:59

保持简单,我会选择static MustSelectKosherBaconBeforeEditAssertMessage = " "。如果存在一些细微的差异,甚至可能对于内联字符串也是如此。

您的 AssertMustSelectKosherBaconBeforeEdit() 看起来太像过早/微观优化。

Keep it Simple, I would go for the static mustSelectKosherBaconBeforeEditAssertMessage = " ". And maybe even for inline strings if there were a few small differences.

Your AssertMustSelectKosherBaconBeforeEdit() looks too much like a premature/micro optimization.

无声无音无过去 2024-09-13 01:27:59

还有一个建议:不要使用静态变量,而是将其设为:

private const string mustSelectKosherBaconBeforeEditAssertMessage = 
    "An error message along the lines - you should not ever be able to " +
    "click on edit button without selecting a something first.";

有关 const 与 static readonly 的更多信息: 链接

不同之处在于 a 的值
静态只读字段在运行时设置
时间,因此可以通过
包含类,而值
const 字段设置为编译时
常数。

也在这里:
http://msdn.microsoft.com/en-us/magazine/cc300489。 ASPX

One more suggestion: rather than static variable, make it:

private const string mustSelectKosherBaconBeforeEditAssertMessage = 
    "An error message along the lines - you should not ever be able to " +
    "click on edit button without selecting a something first.";

More on const vs static readonly: Link

The difference is that the value of a
static readonly field is set at run
time, and can thus be modified by the
containing class, whereas the value of
a const field is set to a compile time
constant.

Also here:
http://msdn.microsoft.com/en-us/magazine/cc300489.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文