Читаем Интернет-журнал "Домашняя лаборатория", 2007 №9 полностью

• методом интерфейса;

• методом с модификатором override. Возможно его задание для virtual-метода. В этом случае атрибут наследуется методами потомков.

Атрибут Conditional, обычно с аргументом DEBUG, сопровождает модули, написанные для целей отладки. Но использование этого атрибута не ограничивается интересами отладки. Зачастую проект может использоваться в нескольких вариантах, например, в облегченном и более сложном. Методы, вызываемые в сложных ситуациях, например, ComplexMethod, имеющий атрибут условной компиляции, будут вызываться только в той конфигурации, где определена константа COMPLEX.

Приведу пример работы с отладочными методами. Рассмотрим класс, в котором определены три метода, используемые при отладке:

public class DebugPrint

{

   [Conditional("DEBUG")] static public void

       PrintEntry(string name)

   {

       Console.WriteLine("Начал работать метод " + name);

    }

    [Conditional("DEBUG")] static public void

        PrintExit(string name)

    {

        Console.WriteLine("Закончил работать метод " + name);

     }

     [Conditional("DEBUG")]

         static public void PrintObject(object obj, string name)

     {

         Console.WriteLine("Объект {0}: {1}", name,

             obj.ToString ());

     }

}

В классе Testing определено поле класса:

int state = 1;

и группа методов:

public void TestDebugPrint ()

{

    DebugPrint.PrintEntry("Testing.TestDebugPrint");

    PubMethod ();

    DebugPrint.PrintObj ect(state, "Testing.state");

    DebugPrint.PrintExit("Testing.TestDebugPrint");

}

void InMethod1()

{

    DebugPrint.PrintEntry("InMethod1");

    // body

    DebugPrint.PrintExit("InMethod1");

}

void InMethod2()

{

    DebugPrint.PrintEntry("InMethod2");

    // body

    DebugPrint.PrintExit("InMethod2");

}

public void PubMethod()

{

   DebugPrint.PrintEntry("PubMethod");

   InMethod1 ();

   state++;

   InMethod2 ();

   DebugPrint.PrintExit("PubMethod");

}

Этот пример демонстрирует трассировку хода вычислений, для чего в начало и конец каждого метода вставлены вызовы отладочных методов, снабжающие нас информацией о ходе вычислений. Такая трассировка иногда бывает крайне полезной на этапе отладки, но, естественно, она не должна присутствовать в финальной версии проекта. Взгляните на результаты, полученные при вызове метода TestDebugPrint в конфигурации Debug.



Рис. 23.1.Трассировка вычислений в процессе отладки


При переходе к конфигурации Release отладочная информация появляться не будет.


Классы Debug и Trace

Атрибут условной компиляции Conditional характеризует метод, но не отдельный оператор. Иногда хотелось бы иметь условный оператор печати, не создавая специального метода, как это было сделано в предыдущем примере. Такую возможность и многие другие полезные свойства предоставляют классы Debug и Trace.

Классы Debug и Trace — это классы-двойники. Оба они находятся в пространстве имен Diagnostics, имеют идентичный набор статических свойств и методов с идентичной семантикой. В чем же разница? Методы класса Debug имеют атрибут условной компиляции с константой DEBUG, действуют только в Debug-конфигурации проекта и игнорируются в Release-конфигурации. Методы класса Trace включают два атрибута Conditional с константами DEBUG и TRACE и действуют в обеих конфигурациях.

Одна из основных групп методов этих классов — методы печати данных: Write, WriteIF, WriteLine, WriteLineIF. Методы перегружены, в простейшем случае позволяют выводить некоторое сообщение. Методы со словом If могут сделать печать условной, задавая условие печати в качестве первого аргумента метода, что иногда крайне полезно. Методы со словом Line дают возможность дополнять сообщение символом перехода на новую строку.

Перейти на страницу:

Похожие книги