Conditional Methods


I saw an internal post today about somebody who wanted to get rid of their #if DEBUG statements in their code, because they were ugly. That made me realize that there's a feature that not everybody knows about, known as conditional methods.

Consider the following code:

using System;
using System.Diagnostics;

class Program {
    static void Main(string[] args) {
        #if DEBUG
        DebugMethod1();
        #endif

        DebugMethod2();
        Console.ReadKey();
    }
    static void DebugMethod1() {
        Console.WriteLine("Debug1");
    }

    [Conditional("DEBUG")]
    static void DebugMethod2() {
        Console.WriteLine("Debug2");
    }
}

In my call to DebugMethod1(), I've used the traditional #if approach to only compile the call if the DEBUG symbol is defined. But in the call to DebugMethod2(), I've used a conditional method that has the same effect - if the DEBUG symbol is not defined, it's as if the call isn't there. That includes any side effects from parameter evaluation - they don't happen.

Note that the docs on the ConditionalAttribute class are a bit misleading.

Comments (16)

  1. can you reformat the code to be on multiple lines? Feel free to reject this comment, of course 🙂

  2. The only problem with that is that the conditional method gets compiled and placed in the assembly, regardless of the attribute.

    That’s too big of a security risk.

    I’d rather stay with #if’s.

  3. Jon Davis says:

    I haven’t seen this, but frankly that still seems like too much work considering your method must likely be void and there is no straightforward way to track what happened. So it looks handy, but limited in purpose.

    There’s some middle ground..

    public static void Main(string[] args) {

    // debuggy thing 1:

    // so much cleaner

    if (Debug) DoSomethingDebuggy();

    // debuggy thing 2

    // good for debug-specific environment variables

    int special = SpecialProperty;

    }

    public int SpecialProperty {

    get {

    if (Debug) return 3;

    return 7;

    }

    }

    public static bool Debug {

    #if DEBUG

    return true;

    #else

    return false;

    #endif

    }

  4. Jon Davis says:

    Typo in there, forgot the get {} in the Debug property, but you get the idea. *shrug*

  5. Jon Davis says:

    Granted, throwing in a runtime conditional degrades performance. To the extent that for some people that actually matters, I retract.

  6. Darren Oakey says:

    Eric –

    thanx

    I didn’t know about conditional – very good!

  7. Matthew W. Jackson says:

    I would hope that the runtime conditional would only degrade performance during the JIT-compile phase. In native code, it shouldn’t exist if it will never be used.

    Can anyone confirm or deny this?

  8. Eric says:

    There is no runtime conditional – it’s all handled at compile time.

  9. Julian Gall says:

    The documentation states that the Conditional attribute determines whether the method is called or not. This implies that the method’s code is still compiled, regardless of the attribute. For a public method, this could lead to unwanted, un-obfuscatable symbols in the application.

    Also, I’d be interested to know the reason why it only works on void methods and not methods with return values or properties.

  10. Delphi Developers' Singapore and Asia Fortress of says:
  11. Delphi Developers' Singapore and Asia Fortress of says:
  12. MBA says:

    Helpful For MBA Fans.

Skip to main content