I am looking for a way to have compile time assertions in the C# programming language, such as those provided by the BOOST library for C++, or the new C++0x standard.
My question is twofold; can this be achieved in standard, portable C#; Alternatively, can the behaviour be achieved via non-portable assumptions of the quirks of a given C# compiler?
A quick search on google revealed the following link to one technique, whose standards compliance and compatibility I am unsure of.
The approach is the same as in other languages that don't have builtin static asserts (Delphi, older C++ and so on): find a mechanism to convert the condition to be asserted into something that the compiler is unhappy about if the condition is false.
For C# one of the easiest mechanisms to exploit is the warning regarding assignment of negative literals/constants to unsigned types. This has already been mentioned in passing somewhere in this discussion (or at least in one of the pages linked from here), but it is worth showing it in its pure form.
Here's an example that guards two constants - MODULUS_32
and MAX_N
from being edited to values that violate expectations:
const uint _0 = (ulong)MODULUS_32 * MODULUS_32 == MAX_N ? 0 : -666;
The -666
makes the error message recognisable as being due to a static assert. Using the ternary operator in this context is preferrable to direct computations because this makes it easier to recognise what's going on (negative results in a computation are more likely to be ascribed to a mistake than explicit, deliberate assignment). Naming the constant something like _MAX_N_must_be_the_square_of_MODULUS_32
makes things even more explicit.
This type of 'static assert' halts compilation reliably - it's not just some warning that could get lost should someone tamper with the /warnaserror
switch.
In certain scopes - for example, within functions - it can be necessary to suppress the 'unused value' warning via a pragma:
#pragma warning disable 219
const uint _0 = (ulong)MODULUS_32 * MODULUS_32 == MAX_N ? 0 : -666;
#pragma warning restore 219
C# is pretty much like Delphi in that it lacks a preprocessor, which means that the static asserts and their mechanisms cannot be packaged into neat macros - if you want to use them then you have to type all the plumbing right then and there. But just like in Delphi, the advantages of getting the compiler to check things at compile time are more than worth the small effort.
Inside a function with a return value, the following trick/hack works (at least with Visual Studio 2005, haven't checked on other platforms):
Something Foo()
{
if (compiletime_const_condition)
{
// ...
return something;
}
// no return statement at all
}
It ain't pretty, but it's the best solution I have so far.
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