I stumbled on a surprising compiler warning using the following code:
private const bool DEFAULT_SETTING = false;
//...
string aString = (DEFAULT_SETTING) ? "1" : "0";
which generates the warning warning CS0429: Unreachable expression code detected
.
After initially being puzzled, I realised the compiler is not wrong because the value of DEFAULT_SETTING
is constant and cannot change. Therefore the ? "1"
part of the ternary operator can never be reached. But neither is the compiler completely right because myself or a future developer may want (or need) to change the default value without breaking the code.
Is there better way to use a default setting similar to the above context which does not generate the warning?
Note: You may want to know why I would want to convert false
into "0"
...it is to save to a settings XML file. When the file is missing, the software automatically generates a shiny new XML file with default settings.
Is there better way to use a default setting similar to the above context which does not generate the warning?
Yes.
But first: stop using SHOUTY_SNAKE_CASING
right now. It makes it look like you're a C programmer. C# uses camelCasing and PascalCasing.
Now to your question. If a named value can change then by definition it is not a constant. Use constants only for things which never change. Pi is a constant. The number of protons in an atom of gold is a constant. The name of your program is not a constant, whether this is the debug or retail build is not a constant, and so on. Those things change.
The compiler is within its rights to warn you about your code because it appears to be making a choice based on something which never changes, and therefore is likely a bug.
This isn't just a convention; the semantics of the C# language assume that a constant will not change ever. For example, if you have a public constant Foo
in Foo.DLL, and it is consumed by code in Bar.EXE, recompiling Foo.DLL with a different value for Foo
does not update the value of Foo
automatically in Bar.EXE. The C# compiler will assume that Foo
will never change and makes a copy of its value in Bar.EXE.
To represent the concept "this thing doesn't change in my program, but it could change in a different instance of my program" use readonly
:
private static readonly bool DefaultSetting = false;
...
string aString = DefaultSetting ? "1" : "0";
You can use compiler directive. this line is the first line:
#define DEFAULT_SETTING
then remain as:
#if DEFAULT_SETTING
string aString = "1";
#else
string aString = "0";
#endif
if you comment the #define DEFAULT_SETTING the string aString = "0"; line is active for compiling otherwise string aString = "1"; is active.
Use an extension like this:
public static class BooleanExtensions {
public static string ToOneOrZero(this bool value) {
return value ? "1" : "0";
}
}
Usage:
var val = DEFAULT_SETTING.ToOneOrZero();
You will not get a warning and it is cleaner-I think.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With