Debug.Assert -s 使用相同的错误消息。我应该将其提升为静态变量吗?
我喜欢断言和代码可读性,但不喜欢代码重复,并且在几个地方我使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用第一种(重复)形式。
原因是:
工作量减少了。断言仅用于调试,因此重复不会给发布版本带来任何低效率。当代码已经具有完美的可读性和功能时,不要浪费时间试图使代码“漂亮”或“优雅”。
我认为它实际上比您的替代方案更短、更具可读性并且更容易维护。
当您在调试器中点击断言时,在代码中包含完整消息非常有用,这样您就可以了解断言的含义。很多程序员使用 Assert(kosherBaconList.SelectedIndex != -1);根本没有任何解释,如果你编写了代码,这很好,但是当你点击别人的断言时,你不知道它意味着什么。也就是说,我知道我称你的方法为“错误”,但我到底需要修复什么才能称其为“正确”?因此,断言消息应该指出问题是什么,以及盯着 Assert() 调用的人需要做什么来修复它。当调试器在测试运行中停止时,您希望它就在您面前。
如果您在 Assert 调用中包含文本,它将不会被编译到您的发布版本中。但是,一旦将其设为静态变量,您就会在发布版本中包含(未使用的)字符串,从而用调试垃圾堵塞它。
如果您想检查多个条件来测试对象的有效性,则可以使用子例程,即
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.
保持简单,我会选择
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.还有一个建议:不要使用静态变量,而是将其设为:
有关 const 与 static readonly 的更多信息: 链接
也在这里:
http://msdn.microsoft.com/en-us/magazine/cc300489。 ASPX
One more suggestion: rather than static variable, make it:
More on const vs static readonly: Link
Also here:
http://msdn.microsoft.com/en-us/magazine/cc300489.aspx