我使用以下代码偶然发现了令人惊讶的编译器警告:
private const bool DEFAULT_SETTING = false;
//...
string aString = (DEFAULT_SETTING) ? "1" : "0";
生成警告warning CS0429: Unreachable expression code detected
。
在最初感到困惑之后,我意识到编译器没有错,因为DEFAULT_SETTING
的值是常量且不能改变。因此,永远无法到达三元运算符的? "1"
部分。但编译器也不完全正确,因为我自己或未来的开发人员可能希望(或需要)在不破坏代码的情况下更改默认值。
是否有更好的方法可以使用类似于上述上下文的默认设置,但不会生成警告?
注意:您可能想知道我为什么要将false
转换为"0"
...它是保存到设置XML文件。当文件丢失时,软件会自动生成一个带有默认设置的闪亮的新XML文件。
答案 0 :(得分:14)
是否有更好的方法可以使用类似于上述上下文的默认设置,但不会生成警告?
是
但首先:立即停止使用button.getModel().setRollover(true);
。这让你看起来像是一名C程序员。 C#使用camelCasing和PascalCasing。
现在回答你的问题。如果命名值可以更改,那么根据定义它不是常量。仅对永不改变的事物使用常量。 Pi是一个常数。金原子中的质子数是常数。程序的名称不是常量,无论是调试还是零售构建都不是常量,依此类推。那些事情发生了变化。
编译器有权向您发出有关您的代码的警告,因为它似乎是基于永不改变的东西做出选择,因此可能是一个错误。
这不仅仅是一个惯例; C#语言的语义假设常量不会改变永远。例如,如果在Foo.DLL中有一个公共常量SHOUTY_SNAKE_CASING
,并且它被Bar.EXE中的代码占用,则使用Foo
的不同值重新编译Foo.DLL会不< / strong>在Bar.EXE中自动更新Foo
的值。 C#编译器将假定Foo
将从不更改并在Bar.EXE中生成其值的副本。
代表概念“这个东西在我的程序中不会改变,但它可能会在我的程序的不同实例中发生变化”使用Foo
:
readonly
答案 1 :(得分:3)
您可以使用编译器指令。 这一行是第一行:
#define DEFAULT_SETTING
然后保持为:
#if DEFAULT_SETTING
string aString = "1";
#else
string aString = "0";
#endif
如果您对 #define DEFAULT_SETTING 发表评论,则字符串aString =“0”; 行有效进行编译,否则字符串aString =“1”; 活跃。
答案 2 :(得分:1)
使用这样的扩展程序:
public static class BooleanExtensions {
public static string ToOneOrZero(this bool value) {
return value ? "1" : "0";
}
}
用法:
var val = DEFAULT_SETTING.ToOneOrZero();
你不会收到警告,它是清洁 - 我想。