Compile time checking of conditional compilation symbols in C# (see example)?
In C/C++ you can do something like:
#define IN_USE (1)
#define NOT_IN_USE (-1)
#define USING( system ) ( 1 / (system) == 1 / IN_USE )
And then:
#define MY_SYSTEM IN_USE
#if USING( MY_SYSTEM )
<my_system impl>
#endif
This sort of setup means:
All conditional compilation symbols have to be defined either IN_USE or NOT_IN_USE.
I can put them all in a single header file (or a couple) and easily turn them on/off and see what conditional compilation symbols there are.
A typo like #if USING( MYSYSTEM ) is caught by the compiler due to div by 0 rather than silently compiling it out.
Is it possible to do this in C#? Is there another best practices way to achieve the same effect?
I realize in C# you can do conditional compilation by setting them in the开发者_开发知识库 project settings and using #if, but I dislike the fact that something doesn't have to be explicitly undefined. This is the reason in the project settings you have the "DEBUG" and "TRACE" checkboxes. If they weren't there, you'd have no idea you could turn them on.
C# doesn't allow preprocessor symbols to be given values, but you can use #define
and #ifdef/#endif
. Typically preprocessor symbols are actually defined at a project level within
the project properties rather than in code.
You may also be interested in ConditionalAttribute
which allows calls to methods decorated with it to be omitted if the relevant preprocessor symbol is not present. (The method itself is still built; it just determines whether calls actually take place or not.)
If you want actual constant values, you can use const
and static readonly
fields instead.
C# doesn't have a preprocessor, but the compiler is smart enough that if you give it a constant as an if() condition, it will emit/not emit code appropriately, giving the same effect.
// in Conditionals.cs
public static class Conditionals
{
public const bool MY_SYSTEM = true;
}
// In SomeOther.cs
if (Conditionals.MY_SYSTEM)
{
// <my_system impl>
}
C# doesn't have the c-preprocessor. It does let you have project-wide or file-wide #define's that can be set to either defined or not-defined. You can use this only from within a #if/#else block and your testing is limited to exists/doesn't exist.
So in your case, in your project settings in VisualStudion, under Build, you would have MY_SYSTEM in the Conditional compilation symbols box.
Generally speaking, you want to factor your modules around class definitions rather than around preprocessor chicanery if at all possible.
精彩评论