0

Please note that I am aware of Debug.Print - the Console.WriteLine is a very simplified example of what I'm trying to do.

Is there a way to have a single line of code which exists only in Debug mode, which does not appear in Release at all?

I have some commands which help me debug the execution of a performance-critical section of code, and I have placed a large number of them all over the function in key places.

Here is an example of what I've done:

using System;
public class C {
    public Object _obj = new object();
    public void M() 
    {
        Alpha("This goes away in Release");
        Alpha(_obj.GetHashCode() + "...but this doesn't");

        #if DEBUG 
            //But I don't want this three line deal.
            Alpha(_obj.GetHashCode() + "...of course this does get removed");
        #endif

    }

    public static void Alpha(String s)
    {
        #if DEBUG
            Console.WriteLine(s);
        #endif
    }
}

The issue is that in release mode, the compiler recognizes that the first call does nothing in release mode, and removes it. But it does not do that in the second call. I know this because I have tested it in SharpLab: https://sharplab.io/#v2:EYLgHgbALANALiAhgZwLYB8CQBXZBLAOwHMACAZQE9k4BTVAbgFgAoTAB22ABs8BjE3lxTISAYRIBvFpnace/APLAAVjV5wSAfQD2KkgF4SBGgHcSu1eoAUASiatZ3PiQBu2vABMSAWVslpmFIOmACCXGwAFohWAEQAKhF4IkTaNCKIJogUJIQkAEo0XDQoNDF2AaHhUVY6KgB0AOI0cAASKBGi2h40fgDUJDF1Q8DYGnCJIh6pyAQAAgC0AIxwZfYymBUAxHgAZiQAIgCiAEIAqg3+wZgA9NfHoyQAkiRTc0samQRjEyTjAE40GgkHjGF7FLh1CqVSLRWrKRrNNrIDpdHo2Ej9QZDbR7XjabB/ZBA8ZJF7TEhEZokAGobQuGgeVZbGgEDy7KEBAC+AQCHCc/GoiDgzjcnhIYRhVjIcD+hFIyBsASC622eyOZwaUM6BGQ2iKdQA6rLaAAZQg9BVrGSbFlsnZc6ScoA==

Is there any way of avoiding the three-line version?

MineR
  • 2,144
  • 12
  • 18

3 Answers3

5

Yes, just put a [Conditional(...)] attribute on the method that you need to "not exist" unless you are using the Debug configuration:

[System.Diagnostics.Conditional("DEBUG")]
public static void Alpha(String s)
{
    Console.WriteLine(s);
}

All calls to such methods are effectively removed (not compiled) unless the specified symbol is present.

Note that a restriction applies: [Conditional(...)] can only be used for void methods.

Peter B
  • 22,460
  • 5
  • 32
  • 69
2

You probably desire ConditionalAttribute:

using System;
using System.Diagnostics;

public class C {
    public Object _obj = new object();
    public void M() 
    {
        Alpha("This goes away in Release");
        Alpha(_obj.GetHashCode() + "...this is ommited");
    }

    [Conditional("DEBUG")]
    public static void Alpha(String s)
    {
        Console.WriteLine(s);
    }
}

See SharpLab for results.

Paweł Dyl
  • 8,888
  • 1
  • 11
  • 27
0

A neat trick you could use for void methods is the ConditionalAttribute, used like this:

[Conditional("DEBUG")]
public static void Alpha(String s)
{
    /***/
}

The compiler would remove all calls to those methods if the symbol is not defined.

Also there's this monstrosity:

if (System.Diagnostics.Debugger.IsAttached) /* your debug */

Works in one line, but requires an attached debugger and also is not "removing" the code.

V0ldek
  • 9,623
  • 1
  • 26
  • 57