logo search
C#, 320 стр

Классы Debug и Trace

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

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

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

По умолчанию методы обоих классов направляют вывод в окно Output. Однако это не всегда целесообразно, особенно для Release-конфигурации. Замечательным свойством методов классов Debug и Trace является то, что они могут иметь много "слушателей", направляя вывод каждому из них. Свойство Listeners этих классов возвращает разделяемую обоими классами коллекцию слушателей - TraceListenerCollection. Как и всякая коллекция, она имеет ряд методов для добавления новых слушателей: Add, AddRange, Insert - и возможность удаления слушателей: Clear, Remove, RemoveAt и другие методы. Объекты этой коллекции в качестве предка имеют абстрактный класс TraceListener. Библиотека FCL включает три неабстрактных потомка этого класса:

Можно и самому создать потомка абстрактного класса, предложив, например, XML-слушателя, направляющего вывод в соответствующий XML-документ. Как видите, система управления выводом очень гибкая, позволяющая получать и сохранять информацию о ходе вычислений в самых разных местах.

Помимо свойства Listeners и методов печати, классы Debug и Trace имеют и другие важные методы и свойства:

У классов есть и другие свойства и методы, позволяющие, например, заниматься структурированием текста сообщений.

Рассмотрим пример работы, в котором отладочная информация направляется в разные каналы - окно вывода, консоль, файл:

public void Optima()

{

double x, y=1;

x= y - 2*Math.Sin(y);

FileStream f = new FileStream("Debuginfo.txt",

FileMode.Create, FileAccess.Write);

TextWriterTraceListener writer1 =

new TextWriterTraceListener(f);

TextWriterTraceListener writer2 =

new TextWriterTraceListener(System.Console.Out);

Trace.Listeners.Add( writer1);

Debug.Listeners.Add( writer2);

Debug.WriteLine("Число слушателей:" +

Debug.Listeners.Count);

Debug.WriteLine("автоматический вывод из буфера:"+

Trace.AutoFlush);

Trace.WriteLineIf(x<0, "Trace: " + "x= " + x.ToString()

+ " y = " + y);

Debug.WriteLine("Debug: " + "x= " + x.ToString() +

" y = " + y);

Trace.Flush();

f.Close();

}

В коллекцию слушателей вывода к слушателю по умолчанию добавляются еще два слушателя класса TextWriterTraceListener. Заметьте, что хотя они добавляются методами разных классов Debug и Trace, попадают они в одну коллекцию. Как и обещано, один из этих слушателей направляет вывод в файл, другой на консоль. На рис. 23.2 на фоне окна кода показаны три канала вывода - окно Output, консоль, файл - содержащие одну и ту же информацию.

Рис. 23.2.  Три канала вывода