views:

1367

answers:

4

The trusty old preprocessor directive in C# appear to work great when I write:

#if DEBUG
...
(Some code)
...
#endif

However, attributes enclosed in the conditional block appear to continue to get processed and I get errors indicating such. For instance, surrounding an [AssemblyVersion(...)] within the conditional block appears to have no affect.

I can go into the details as to why we want to conditionally ignore the [AssemblyVersion(..)], but it's irrelevant. Any ideas?

Thanks! - Sean

A: 

Are you sure you're not building in release mode?

yoyoyoyosef
It is release mode. In this case, in the release configuration, the block within "#if DEBUG" is still being processed.
CleverCoder
+4  A: 

This works correctly for me. In my AssemblyInfo.cs file, I have the following:

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif

Looking at the compiled assembly in Reflector, I see the correct attributes.

You should make sure that your DEBUG symbol is only defined in the project properties and not any where else in your code as an actual #define DEBUG instruction. If you have it defined directly in code it will only be in effect for that file, not the entire project. Defining it in the project properties will cause it be in effect for the entire project.

Scott Dorman
This is strange. With a simple console app, it works properly (selecting release mode, it DOES ignore the attribute within the #if DEBUG block!).. Doing more research... The project in question is a class library. Gonna figure this out...
CleverCoder
THe project that I pulled the example code from is also a class library so that should have no effect on the behavior. I have seen circumstances where #if DEBUG doesn't work but #if Debug does, mostly due to things being defined incorrectly. Check your project properties and make sure you don't have any #define directives.
Scott Dorman
A: 

simpler - you can tag your debug function(s) with the metadata tag [Conditional]:

#define DEBUG1

...

public static void PrintText1(string txt)   {
    Console.Write("This is PrintText2\n");
}

[Conditional("DEBUG1")]
public static void PrintText2(string txt)   {
    Console.Write("This is PrintText2\n");
}

[STAThread]
static void Main(string[] args)    {
    PrintText1("This is the unconditional method");
    PrintText2("This function will be called only if 'DEBUG1' is defined");
}

try it!

Also, what I noticed is that #define only exists within the context of the file it is defined, ex calling PrintText2 from another file, where debug is not defined, will not execute. This also works the other way around:

[Conditional("DEBUG1")]
public static void ConditionedPrint(string txt) {
    Console.Write("This is PrintText2\n");
}

public static void UnconditionedPrint(string txt)     {
    ConditionedFunc(txt);
}

UnconditionedFunc will print "This is PrintText2\n" iff (if and only if) #define DEBUG1 was defined in this file, regardless of the other files.

There is also System.Diagnostics.Debug, I'm not sure what it does though.

Nefzen
That works for things that accept an attribute, but the attribute itself needs to be conditional.. It IS working for a simple project, so it's something project related.. Thanks for the tip! That is a neat new attribute.
CleverCoder
oh sorry, I didn't notice you wanted metadata tags also conditioned. What I can tell you is that `#define` in C# only exists in the context of the same file, so that might be the cause. VS should mark out the lines that are not going to be compiled, so you should notice a visual difference when it's working like you want it to.
Nefzen
The Conditional attribute will only work for void functions.
Scott Dorman
I suppose that only makes sense
Nefzen
+1  A: 

I figured it out! There was a key piece of information I neglected to mention: that it was a Workflow project (Guid {14822709-B5A1-4724-98CA-57A101D1B079}). It turns out that there is a bug with the workflow project type, specifically the Workflow.Targets file that is included in the build file.

It appears that the preprocessor acts as though the DEBUG constant is defined. You can repro the issue by creating a workflow project and adding this to the AssemblyInfo file:

#if DEBUG
[assembly: AssemblyFileVersion("1.0.0.0")]
#endif

Then try a release build. I filed this with MS: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=466440

Best regards! -Sean

CleverCoder
You should have edited the original and added this information. Technically, this is not the correct answer because the question was asked incorrectly :)
RKitson