There are already few questions on this topic but no answer I need. They only give examples how it works. But I need deeper explanation: why does it exist and what are good ways of using it (if any =) ).

Basically I know how to use it, but for me the usage looks odd. Let's look at example:

For me this is completely different from using #if conditional build with project-defined conditional compilation symbols. If we use project-defined symbol, it is attached to project build configuration and we can manage code needed to build (and excluded from build) with build configuration used. So code

#if DEBUG
Console.WriteLine("Debug log message");
#endif

is fine for me. But as I said it is completely different from using #define directive because it is managable.
Am I correct that 1st example can be managed only manually commenting/uncommenting #define line on every build? If yes, it is not managable, hard-to-maintain and I think this usage of #define is extreemely bad practice and sholdn't exists in the language at all.

I can imagine usage of #define/#undef inside #if statement. Something like

Sorry for so complicated example, but that is at least something I can find useful. Though I wouldn't write such code in any way =).
Is there any good usage of #define?

PS: I never used #define myself for 5 years and had no will to do it, but I got a support project which has many strange defines which even named in an odd way. Those defines usually placed at the top of the file, like in my 1st example here. And I have no idea how to maintain this code.

2 Answers
2

I can't see any valid reason for it other than without it, the #IF statement wouldn't exist.

When you define project level precondition variables using the /define directive on the compiler all it really does is add a #DEFINE to the code.

I would argue that this makes it manageable but not in setting it manually in the code, using the /define statement.

The other usefulness is readability and scope. Project defined statements apply to the project, #DEFINE level statements only apply to one file. This helps keep things organised, readable and stops variable issues.

Sorry, I don't understand what you mean under redability and scope here. Defining symbol in a file is the same as removing all code that not match conditions and remove #if conditions with this symbol. The only way to use it is less commenting/uncommending during debug. But why should this be present in release code? Under managable I mean ability to change it, running different build scripts or different build configurations in VS.
–
Oleksandr PshenychnyyJul 27 '12 at 10:10

@OleksandrPshenychnyy apologies if answer wasn't very clear, I would agree that it is highly unmanageable in the current form. The only benefit of having it listed in a file is you know its there, you can read it at the top of the file and know it supports these variables. I think most of the things you can do with define statements you can do with well managed code. You may take an extra OP or two, but if you REALLY REALLY want micro-optimization then it will be handy, but again if you need it optimized this much maybe C# isn't the choice :D
–
John MitchellJul 27 '12 at 10:13

Thanks. Optimization is probably the last thing considered in that project =). But if you agree that #define isn't a good practice, I don't understand why it even exists in the C# language. You said compiler places it in the code (in every file??) when we use VS prject conditional symbol. That might be the reason actually, but I think it was possible to prohibit developers to write it in code.
–
Oleksandr PshenychnyyJul 27 '12 at 10:30

'#define' is there because people expect it to be there. :) For your purposes (e.g. a large project) it may make more sense to keep preprocessor symbols in your project. For quick debugging or other purposes #define may be the best choice. Additionally, #define allows fine-grained (file level) control of symbols.

Imagine you have a large codebase and a single module that is giving you trouble. You might wish to '#define TRACE' or '#define DEBUG' only in the single file where you want to enable tracing/debugging for performance reasons.

I afraid defining DEBUG symbol will not give you ability to debug code. From your words #define should be used only on project stabilization phase, for quick-fixes and logs. But I don't want to believe this construction exists only for this reason =)
–
Oleksandr PshenychnyyJul 27 '12 at 10:02

It's really a completeness thing. People who have grown accustomed to the C/C++ preprocessor are going to expect (as much as C# allows) a similar experience. That means being able to add preprocessor directives either via command line or in-code text. Being able to do both means the developer has more tools to work with. For example, imagine you have some service using CodeDom's compiler and you can only give it text to compile. You might like to use #if in that code for whatever reason, which means you need #define.
–
Chip NorkusJul 27 '12 at 10:10