One more variant, based on implicit numeric type conversions. Let's consider this:
public static class Generic {
public const byte Zero = 0;
public const sbyte SignedZero = 0;
}
Apparently, as all other numeric types, excluding
sbyte
are wider then byte, it works:
uint ui = Generic.Zero;
int i = Generic.Zero;
long l = Generic.Zero;
ulong ul = Generic.Zero;
short sh = Generic.Zero;
ushort ush = Generic.Zero;
decimal d = Generic.Zero;
double dbl = Generic.Zero;
Single sng = Generic.Zero;
byte b = Generic.Zero;
sbyte sb = Generic.SignedZero;
Naturally only
byte
and
sbyte
are incompatible without explicit conversion, but all other numeric type are compatible with both
byte
and
sbyte
.
If such asymmetric schema (not fair to either
sbyte
or
byte
:-)) seems a bit ugly, another option is to distribute the universal constants equally between signed and unsigned types:
public static class Signed {
public const sbyte Zero = 0;
}
public static class Unsigned {
public const byte Zero = 0;
}
In this case, if all signed types (including both floating-point) use
Signed.Zero
, and all unsigned types use
Unsigned.Zero
, it will work. Again, it looks somewhat redundant, because all types weider then
byte
and
sbyte
can use either variant.
Is it good or bad? The problem is some performance cost related to implicit conversion. This is a runtime operation, so the performance will be not as good as with same-type constant or just with
immediate constant zero, which are known at compile time. (In some languages, such as Borland Pascal or Deplhi Pascal, there are "real" generic constants. Types are not declared, and the compiler generates real immediate constant depending on the type of target object. C and C++ have "#define", which is an apparent lame.)
What's better? Still,
default(TYPE)
. All out inventions should be considered with some humor, even though we touch serious aspects of programming.
[EDIT]
I almost forgot: it's also good to have the definition for
One
, to make sure that we can completely get rid of all immediate constants in any code. All other values can be made explicitly declared constants and put in some special files with definitions, or even in data files and resource.
Also, good to mention one similar issue: null should be considered acceptable (by the way, the scheme shown above will also cover nullable numeric types (like
int?
). As to "", it should be exterminated first. The only acceptable alternative is
string.Empty
.
Note that Solution 3, as it is shown in its text, covers all types at once, but
string.Empty
is still needed as
default(string)
is of course null.
—SA