tags:

views:

226

answers:

4

Is it possible to create a method which performs debugging assistance like the System.Diagnostics.Debug class?

I'm looking for a way to construct a method which when called by an assembly compiled with the DEBUG conditional compilation symbol defined, results in an operation, and which is a no-op when called by an assembly without the symbol defined.

If possible, I'd like it to be possible for the calls to the debugging methods to add minimal overhead or increase in size to the release version of the assembly.

To clarify, the debugging methods should be in an assembly compiled in Release mode. Calls to the methods should only generate operations when called from an assembly with the DEBUG symbol defined in the scope of the method call.

+6  A: 

ConditionalAttribute

BTW the code for the method being called remains in the assembly -- it's the calls to it that are removed at compilation time

Bonus topical blog post: http://blogs.msdn.com/ericlippert/archive/2009/09/10/what-s-the-difference-between-conditional-compilation-and-the-conditional-attribute.aspx

Ruben Bartelink
+19  A: 

Add the Conditional attribute to the method, like this:

[Conditional("DEBUG")]
public void Whatever() {
    //...
}

Note that the method must return void, and cannot have any out parameters; otherwise, it would be impossible to remove a call to it.

The method will be compiled into the assembly, but CLS-compliant compilers will only emit calls to the method if the assemblies that they are compiling has DEBUG defined. Note that the C++ compiler is not CLS-compliant and will always emit the call.

SLaks
+1 for pointing out that Conditional it's not foolproof (does that mean it's even CLI-compliant?) What happens for C++ calls to Debug.WriteLine? Is that for all versions? It/d be nice to have you edit that in :P
Ruben Bartelink
I haven't actually tried it. The MSDN page on ConditionalAttribute just says that the C++ compiler isn't compliant, without saying which versions.
SLaks
As I stated in the answer (`and will always emit the call`), the C++ compiler (I believe) will always emit calls to `WriteLine`, even in Release.
SLaks
I would think that non-void or "with out params" methods should be a compile error if the ConditionalAttribute is applied.
Simon
Yes, it is a compiler error.
SLaks
+2  A: 

If you disassemble System.Diagnostics.Debug class using Reflector you can see that this is done using the [Conditional("DEBUG")] attribute:

public sealed class Debug
{
    private Debug();
    [Conditional("DEBUG")]
    public static void Assert(bool condition);
    // etc...
}
Kragen
A: 

If you need another signature than void func(..) without out parameters, what would be wrong with

MyDebugObject Foo(out int justForGrins)
{
    justForGrins = <safe value for release builds>;
    MyDebugObject result = <safe value for release builds>;
    #if DEBUG
     .. run code you need for your debugging...
    #endif
     return result;
}

It is more verbose and less elegant than the ConditionalAttribute, but it would allow you a more flexible signature.

Sam Dahan