C# 关于C中有效登录的问题#
我编写了一个用于调试的简单类,并在代码中调用方法Debugger.WriteLine(…),如下所示:C# 关于C中有效登录的问题#,c#,debugging,trace,C#,Debugging,Trace,我编写了一个用于调试的简单类,并在代码中调用方法Debugger.WriteLine(…),如下所示: Debugger.WriteLine("[Draw]", "InProgress", "[x,y] = " + x.ToString("0.00") + ", " + y.ToString("0.00") + "; pos = " + lastPosX.ToString() + "x" + lastPosY.ToString() + " -> " +
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调用中调用String(),这代价很高,因为它会创建新字符串(例如更改数字)。如何解决这个问题
关于调试/跟踪的几点/问题:
- 我不想将每个Debugger.WriteLine都封装在IF语句中,也不想使用预处理器指令来省去调试方法,因为这将不可避免地导致代码不太可读,并且需要太多的键入
- 我不想使用任何框架进行跟踪/调试。我想试着自己编程
- 如果在发布模式下编译,是否会忽略?如果是这样的话,我的方法是否也会有类似的行为
- 有了这些,我可以做到: output=String.Format(“您现在{0}岁。”,岁)
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
}
}
或
当然,你会根据自己的需要修改它。如果#if DEBUG/#endif内置用于在调试器中显示其自身状态,则可以创建成员方法,而不是创建单独的类
对于日志记录,请查看诸如Log4net或企业库之类的框架。它们以多种方式配置日志记录。即使你想登录
HTH使用Reflector,我发现Debug.Writeline是这样声明的:
[Conditional("DEBUG")]
public static void WriteLine(string message)
这意味着在发布模式下,对该方法的所有调用都将从代码中消除
例如,此代码:
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());
}
我使用的模式是定义一个日志接口(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类中了解日志记录情况的需要。基本固体材料。因此,“top”(比如控制台的main()方法)将具有IF DEBUG指令,然后传入记录器的正确实现。此方法中真的存在性能问题吗?@harpo:创建了许多不可变字符串。一次调用并不太糟糕,但是如果这个方法输出的频率足够高,那么由于所有的字符串对象分配,速度会变慢。我不相信StringBuilder在这种情况下会有什么不同。由于字符串是在单个语句中组装的,编译器不会为每个串联创建中间字符串。(AFAIK)@harpo:这是我从未听说过的编译器优化。据我所知,字符串操作是不可变的,任何连接或扩充都会创建一个新的操作,不管它在哪里使用。harpo是对的:编译器用字符串替换a+b+c。Concat(a,b,c)我的方法的内容被编译指令包围。但如何使用StringBuilder,并且仍然只有一行调试方法调用?@Paul Sasik:使用Reflector,自己看看+1;-确认您所说内容的链接。谢谢您的建议!我在想[有条件的(“FakeLogger”),[有条件的(“MyLogger”),。。。上课。也许它也可以作为您的解决方案。记录器的更改将是VisualStudio中更改模式的问题。酷!我认为最重要的一点是从你的类中去掉依赖性。。。您的类不应该关心日志记录是如何实现的,它应该声明它需要日志记录。同样,这只是来自可靠的原则——控制反转和依赖注入。stakx:我认为这是相关的,因为您可以在发布代码中启用跟踪,从而影响应用程序性能。
var mc = new MyClassThatLogs(new FakeLogger());