views:

377

answers:

3

I am trying to enhance my Logger class with some conditionals to control what to log and where to log. I've got two kinds of logging functions:

public static class Logger
{
    [Conditional("Logging"), Conditional("VerboseLogging")]
    public static void Log(string msg, string filename)
    {
        // log to file
    }

    [Conditional("VerboseLogging")]
    public static void VerboseLog(string msg, string filename)
    {
        Log(msg, filename); // just defer call to Log(string msg)
    }
}

However, running the following program

#define Logging
#define VerboseLogging

static void Main(string[] args)
{
    Logger.Log("Logging", "");
    Logger.VerboseLog("VerboseLogging", "");
}

yields only the output "Logging", missing "VerboseLogging".

Debugging the application showed that VerboseLogging indeed does get called, but it does not call Log(msg, filename). The debugger simply jumps right over the function call to the end of the VerboseLog() function.

When I remove the conditionals from the Log(string msg) method, it works.

Does anybody have a clue as to why this happens or what to do so it will be called?

A: 

Are the conditionals not upside down there? i.e.

[Conditional("Logging")]
public static void Log(string msg, string filename) { }

[Conditional("Logging"), Conditional("VerboseLogging")]
public static void VerboseLog(string msg, string filename) {
    Log(msg, filename); // just defers call to Log()
}
Eoin Campbell
No, i don't believe so. The OP wants Log to occur in both situations but VerboseLog to only occur for the VerboseLogging condition.
Jeff Yates
Regardless, he still has both VerboseLogging and Logging defined.
Josh G
Jeff Yates is right. Log should occur in both cases, VerboseLog only if VerboseLogging is defined.
Michael Barth
@Josh G: Yeah, but that does do no harm. Even if I only define VerboseLogging, it's still not working :(
Michael Barth
http://msdn.microsoft.com/en-us/library/4xssyw96.aspx has some info about the Logical AND/OR behaviour of Conditionals but from my reading of that page... your example should be working
Eoin Campbell
A: 

No real help, but the code you posted works fine here for me (.NET 3.5 SP1 console application). Of course I need to remove the filename parameter since your calls in main don't supply it, but other than that both defines gave me both logs and removing the verbose define only logged "Logging".

Applying Occam's razor to the problem: Since the code you posted obviously isn't direct from your source (no body for log method and the missing parameters) are you sure that you've spelt the defines correctly in your original source? Other than that I have no idea why it isn't working for you...

Martin Harris
Thank you for testing the Code! I copied "VerboseLogging" everywhere, still does not work. Oddly enough, the VerboseLog()-method DOES get called, but it does no call Log() inside the body. It jumps over it.
Michael Barth
Ah, now that the real answer has been posted I can see that cutting corners and putting all the classes in a single source file was not the most intelligent way to test this problem. Live and learn I guess...
Martin Harris
+3  A: 

Note that you need to define Logging and VerboseLogging in your Logger file also, because VerboseLog will not call Log if Logging is not defined there.

To add a project-wide conditional define, right click on your Project, and select Project Properties. Then go to the Build tab and enter "Logging, VerboseLogging" to the "Conditional compilation symbols" text box.

Groo
That was it! Thank you.
Michael Barth