Reputation: 105037
I have seen in Debugging .net 2.0 Applications the following code
[Conditional("DEBUG")]
void AssertTableExists() {
#if DEBUG
...
#endif
}
Is there any reason to use the #if directive? I mean, from what I understand the method will only be called if the DEBUG is defined, so I don't see a point in having the #if in the method body.
Upvotes: 8
Views: 3452
Reputation: 659994
Coincidentally I just happened to answer your question on my blog last week.
The #if directive is necessary if the body of the method refers to entities which are themselves declared under #if DEBUG directives. For example
#if DEBUG
static private int testCounter = 1;
#endif
[Conditional("DEBUG")] void CheckConsistency()
{
#if DEBUG
testCounter++;
#endif
...
That would not compile in the release build if you omitted the #if DEBUG in the method body.
Upvotes: 20
Reputation: 21271
Actually there are a lot of differences. ConditionalAttribute looks cleaner in code but it has a lot of limitations and at least one advantage over #if.
#if completely removes code from compilation if symbol is not defined.
#if gives you better control over granularity - you can surround one line inside a method or whole method or certain members of a class of even whole class.
#if allows you to write complex conditions like this:
#if DEBUG & !NO_NETWORK
#if has #else and #elif to allow more complex scenarios.
[Conditional] is only applicable to a single whole method returning void.
[Conditional] includes code into compiled assembly but removes all calls to it. If somebody references your assembly, he would see methods marked with [Conditional] and would be able to use them - this is something you can't achieve with #if.
It's interesting to open .Net Framework assemblies with reflector, find methods marked as Conditional["DBG"] and see their usage. None of them, even internal ones, are used anywhere! That's because Microsoft compiled .Net for release without symbol "DBG" defined but they were actually using those methods to debug .Net during development.
As a last note I must say that conditional compilation sometimes plays evil games when you get completely different behavior in debug and release versions and you only find out about it after you deploy your code and users start complaining. So as a rule of thumb, try to avoid changing behavior with #if, use it only to change input data.
Here's an example of using #if - different application configuration for debug and release versions.
static string ConnectionString
{
#if DEBUG
get { return "<debug connection string>"; }
#else
get { return "<release connection string>"; }
#endif
}
Upvotes: 10