Can I decorate a method in C# such that it is compiled only in debug versions?

I'm aware that you can use #if DEBUG and the likes in C#, but is it possible to create a method, or class, that is ignored completely, including all usages that are not wrapped inside an #if DEBUG блок?

Что-то вроде:

[DebugOnlyAttribute]
public void PushDebugInfo()
{
    // do something
    Console.WriteLine("world");
}

а потом:

void Main()
{
    Console.WriteLine("hello ");
    Xxx.PushDebugInfo();
}

which, if DEBUG is defined will print "hello world", otherwise just "hello ". But more importantly, the MSIL should not contain the method-call at all in release builds.

I believe the behavior I'm after is something similar to Debug.WriteLine, whose call is completely removed and has no impact on performance or stack depth in release builds.

And, if possible in C#, would any.NET language using this method behave the same (ie, compile-time vs run-time optimization).

Also tagged f#, because essentially I will need this method there.

3 ответа

Решение

Кажется, ты ищешь ConditionalAttribute,

Например, это часть Debug Исходный код класса:

static partial class Debug
{
    private static readonly object s_ForLock = new Object();

    [System.Diagnostics.Conditional("DEBUG")]
    public static void Assert(bool condition)
    {
        Assert(condition, string.Empty, string.Empty);
    }

    [System.Diagnostics.Conditional("DEBUG")]
    public static void Assert(bool condition, string message)
    {
        Assert(condition, message, string.Empty);
    }
 ................................

Я видел следующий метод, используемый в некоторых местах, хотя это может быть не лучшим способом.

public static class Debug
{
    public static bool IsInDebugMode { get; set; }

    public static void Print(string message)
    {
        if (IsInDebugMode) Console.Write(message);
    }
}

Затем вы можете установить IsInDebugMode логическое где-то в вашем основном методе и сделать Debug.Print("yolo") звонки по всему.

РЕДАКТИРОВАТЬ: Это, конечно, может быть расширен с помощью дополнительных оболочек для форматированного вывода, с автоматическим переводом строки и так далее.

Вы можете украсить свой метод с [Conditional("DEBUG")] так что он выполняется только в режиме отладки и не будет выполняться в режиме выпуска.

Вы можете прочитать больше об атрибуте Conditional на MSDN, который гласит:

Условный атрибут часто используется с DEBUG идентификатор для включения функций трассировки и ведения журнала для отладочных сборок, но не в сборках выпуска

Другие вопросы по тегам