none
System.Diagnostics.Conditional("DEBUG") RRS feed

  • Вопрос

  • Доброго времени суток.

    Если к методу применить атрибут System.Diagnostics.Conditional("DEBUG") с обозначенным параметром, то в случае компиляции RELEASE версии (т.е. при отсутствии символа условной компиляции DEBUG), вызов данного метода в исходном коде будет отовсюду исключен. Однако сам метод, помеченный этим атрибутом останется (просматривал через ILSpy), хотя необходимость в нём полностью исчезает. Как сделать так, чтобы в обозначенной ситуации из результирующей сборки исключался и сам метод?

    С уважением Андрей


Ответы

  • Его (компилятор), его же оружием ( частичные методы). Никаких следов...допилил свою же идею.

    //#define DEBUG
    #define RELEASE
    namespace ConsoleApplication
    {
      public partial class Program
      {
        static void Main(string[] args)
        {
          //Этого метода не будет при RELEASE.
          MethodDebug();
          MethodRelease();
        }
        static partial void MethodDebug();
        static partial void MethodRelease();
      }
      //Нет реализации, нет методов. Компилятор убирает все частичные методы
      //если они не определены.
      //Этого кода тоже.
    #if DEBUG
      public partial class Program
      {
        //Компилируется только в режиме debug
        static partial void MethodDebug()
        {
          System.Console.WriteLine("Отладка.");
        }
      }
    #endif
    #if !DEBUG
      public partial class Program
      {
        //Компилируется только в режиме release
        static partial void MethodRelease()
        {
          System.Console.WriteLine("Релиз.");
        }
      }
    #endif
    
    }


    8 июня 2012 г. 12:32
    Модератор

Все ответы

  • Используйте директивы условной компиляции. Вот небольшой пример

    #define DEBUG
    namespace ConsoleApplication
    {
      class Program
      {
        static void Main(string[] args)
        {
    
        }
    #if DEBUG
        //Компилируется только в режиме debug
        public static void MethodDebug()
        {
    
        }
    #endif
    #if !DEBUG
        //Компилируется только в режиме release
        public static void MethodRelease()
        {
    
        }
    #endif
      }
    }

    • Предложено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 10:19
    8 июня 2012 г. 10:08
    Модератор
  • я думал об этом, но данный подход неудобен. Ведь если в #if упаковать методы, но в #if придётся упаковывать и каждый вызов этого метода в коде, иначе в RELEASE метод будет отсутствовать, а его вызовы останутся.
    8 июня 2012 г. 10:19
  • Долго думал, как же схитрить и обмануть компилятор. Додумался используя частичные методы(C#3.0 и высше). Я называю их методами призраками. Вот решение, почти полное.

    //#define DEBUG
    #define RELEASE
    namespace ConsoleApplication
    {
      class Program
      {
        static void Main(string[] args)
        {
          DebugClass.MethodDebugInvoker();
          DebugClass.MethodReleaseInvoker();
        }
      }
      public static partial class DebugClass
      {
        static partial void MethodDebug();
        static partial void MethodRelease();
        [System.Diagnostics.Conditional("DEBUG")]
        public static void MethodDebugInvoker()
        {
          MethodDebug();
        }
        [System.Diagnostics.Conditional("RELEASE")]
        public static void MethodReleaseInvoker()
        {
          MethodRelease();
        }
      }
    #if DEBUG
      public static partial class DebugClass
      {
        //Компилируется только в режиме debug
        static partial void MethodDebug()
        {
          System.Console.WriteLine("Отладка.");
        }
      }
    #endif
    #if !DEBUG
      public static partial class DebugClass
      {
        //Компилируется только в режиме release
        static partial void MethodRelease()
        {
          System.Console.WriteLine("Релиз.");
        }
      }
    #endif
    
    }

    Следы всё же остаются. Но очень красивое и элегантное.


    • Изменено YatajgaEditor 8 июня 2012 г. 12:34 Опечатки
    8 июня 2012 г. 12:30
    Модератор
  • Его (компилятор), его же оружием ( частичные методы). Никаких следов...допилил свою же идею.

    //#define DEBUG
    #define RELEASE
    namespace ConsoleApplication
    {
      public partial class Program
      {
        static void Main(string[] args)
        {
          //Этого метода не будет при RELEASE.
          MethodDebug();
          MethodRelease();
        }
        static partial void MethodDebug();
        static partial void MethodRelease();
      }
      //Нет реализации, нет методов. Компилятор убирает все частичные методы
      //если они не определены.
      //Этого кода тоже.
    #if DEBUG
      public partial class Program
      {
        //Компилируется только в режиме debug
        static partial void MethodDebug()
        {
          System.Console.WriteLine("Отладка.");
        }
      }
    #endif
    #if !DEBUG
      public partial class Program
      {
        //Компилируется только в режиме release
        static partial void MethodRelease()
        {
          System.Console.WriteLine("Релиз.");
        }
      }
    #endif
    
    }


    8 июня 2012 г. 12:32
    Модератор
  • Да, неплохая идея, спасибо. Правда это будет работать только с методами, возвращающими void (частичные только такими и могут быть, если мне не изменяет память).

    8 июня 2012 г. 12:51
  • "Правда это будет работать только с методами, возвращающими void (частичные только такими и могут быть, если мне не изменяет память)." - да именно так, но можете использовать ref параметры, чтобы что-то вернуть из метода. Но обычно, отладочные методы ничего не возвращают.
    8 июня 2012 г. 12:55
    Модератор
  • Небольшой оффтоп.

    Если хочется максимальной гибкости в настройке компиляции приложения, то можно посмотреть в сторону AOP - аспектно-ориентированного программирования. В AOP-фреймворках можно внедрять дополнительный код (скажем, логгирование) в любые методы. В качестве ориентира, что смотреть - PostSharp.

    8 июня 2012 г. 22:09