我编写了一个简单的调试类,我在我的代码中调用了Debugger.WriteLine(...)方法,如下所示:
Debugger.WriteLine("[Draw]", "InProgress",
"[x,y] = " + x.ToString("0.00") +
", " + y.ToString("0.00") +
"; pos = " + lastPosX.ToString() + "x" +
lastPosY.ToString() + " -> " + posX.ToString() +
"x" + posY.ToString() + "; SS = " +
squareSize.ToString() + "; MST = " +
startTime.ToString("0.000") + "; Time = " + time.ToString() +
phase.ToString(".0000") + "; progress = " +
progress.ToString("0.000") + "; step = " +
step.ToString() + "; TimeMovementEnd = " +
UI.MovementEndTime.ToString()
);
Debugger.WriteLine过程的主体仅在调试模式下编译(指令#if,#endif)。让我担心的是我经常在Debugger.WriteLine调用中需要ToString(),因为它会创建新的字符串(例如,用于更改数字)。如何解决这个问题?
有关调试/跟踪的几点/问题:
我不想将每个Debugger.WriteLine包装在IF语句中或使用预处理器指令以省略调试方法,因为它不可避免地导致代码不太可读而且需要输入太多
我不想使用任何框架进行跟踪/调试。我想尝试自己编程。
如果在发布模式下进行编译,是否会遗漏Trace methods?如果是这样,我的方法可能会表现得相似吗?
使用static String.Format method,我可以这样做:
output = String.Format(“你现在已经{0}岁了。”,年);
哪个好看。它是ToString()问题的解决方案吗?
答案 0 :(得分:4)
使用Reflector我发现Debug.Writeline以这种方式声明:
[Conditional("DEBUG")]
public static void WriteLine(string message)
这意味着在Release模式下,所有对此方法的调用都将从代码中消除。
例如这段代码:
public static void Test(int a)
{
string b = Console.ReadLine();
Debug.WriteLine(a + " " + b);
Console.WriteLine(a + " " + b);
}
在发布模式下编译为:
public static void Test(int a)
{
Console.WriteLine(a + " " + Console.ReadLine());
}
答案 1 :(得分:3)
使用StringBuilder创建输出字符串,而不是连接每个值。
您可以创建自己的自定义调试器(MyDbg)类,其中包含WriteLine成员,其内容可以包含在编译指令中。它不会完全编译出调试代码,但会将MyDbg.WriteLine调用转换为无操作。
以下是该课程的快速草图:
using System;
using System.Text ;
public static class MyDbg
{
public static void WriteLine(string str) // and some other params
{
#if DEBUG
StringBuilder sb = new StringBuilder();
sb.Append(str);
// etc. appending other params as you see fit
#endif
}
}
OR
[Conditional("DEBUG")]
public static class MyDbg
{
public static void WriteLine(string str) // and some other params
{
StringBuilder sb = new StringBuilder();
sb.Append(str);
// etc. appending other params as you see fit
}
}
您可以根据自己的需要对其进行修改。而不是创建一个单独的类,您可以创建一个成员方法,如果#if DEBUG /#endif内置在调试器中时显示自己的状态。
答案 2 :(得分:2)
对于Logging,请查看Log4net或Enterprise库等框架。它们可以通过多种方式配置日志记录。即使您想要登录。
HTH
答案 3 :(得分:1)
使用string.Format()
,通过查看代码(恕我直言),实际上可以更容易地识别预期输出:
Debug.WriteLine(string.Format(
"[Draw]InProgress[x,y] = {0:0.00}, {1:0.00}; pos = {2}x{3} -> {4}x{5}; ...",
x, y,
lastPosX, lastPosY,
posX, posY,
...));
答案 4 :(得分:1)
我使用的模式是定义一个日志接口(ILogger),它将依赖注入所有类
public class MyClassThatLogs
{
public MyClassThatLogs(ILogger logger)
{
try
{
logger.Write("bla bla bla");
}
catch(Exception ex)
{
logger.Write(ex); //overload of Write() that takes in an Exception
}
}
}
因此,当你新建它时,你可以传入一个'真正'的记录器或模拟/伪造的
var mc = new MyClassThatLogs(new FakeLogger());
现在你已经抽象出了在MyClassThatLogs类中了解日志记录的必要性。基本的SOLID东西。所以'top'(比如控制台的main()方法)会有IF DEBUG指令,然后传递记录器的正确实现。
答案 5 :(得分:0)
您不需要换行。只需编写包含Debug.WriteLine的辅助方法,然后按标志(通常是bool)打开/关闭它。
即使在发布模式下,跟踪也会在您的代码中。您可以对其进行配置,请参阅http://msdn.microsoft.com/en-us/library/system.diagnostics.tracelistener.aspx
string.Format在内部对参数调用ToString(),因此没有任何好处。