关于C#中有效登录的问题

时间:2010-04-14 18:49:00

标签: c# debugging tracing

我编写了一个简单的调试类,我在我的代码中调用了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()问题的解决方案吗?

6 个答案:

答案 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)

  1. 您不需要换行。只需编写包含Debug.WriteLine的辅助方法,然后按标志(通常是bool)打开/关闭它。

  2. 即使在发布模式下,跟踪也会在您的代码中。您可以对其进行配置,请参阅http://msdn.microsoft.com/en-us/library/system.diagnostics.tracelistener.aspx

  3. string.Format在内部对参数调用ToString(),因此没有任何好处。