最近,一位同事让我对我们的一些日志进行了一些改进,因为他无法找出问题,因为日志没有给他提供有意义的信息。
我首先想到的是直接在String.Format
调用中使用Debug
打印有关对象的更多信息(我们目前正在使用log4net)。我立刻改变了这一思路,只是在模型上实现了ToString
方法,并记录了相反,因为我可以在代码中的多个位置记录这个相同的类,并且只想在一个地方实现格式化
最后,这是当前的解决方案:我在违规类和子类上实现了ToString
,然后继续记录类本身。
在考虑了一下之后,我想知道这是否是正确的方法,或者是否有另一种更优雅/更正确的方法。
我在这个问题上发现了一些帖子,比如this one,但没有足够的结论。我甚至想知道使用DebuggerDisplayAttribute
是否是一个不错的做法:它用于调试目的,如日志记录。 Log4net也支持was被称为ObjectRenders that can be used for such purposes,但我觉得这对于log4net来说有点奇怪而且非常具体。
我觉得这个问题足够广泛,可以涵盖所有面向对象的语言,但我的特殊情况是.Net。在记录和使用ToString
方法方面是否有明确的最佳实践?
答案 0 :(得分:1)
这里唯一重要的问题是:是否有其他上下文可以访问ToString()
?例如,它是否直接数据绑定在UI上?如果没有,那么ToString()
可能就好了,假设对象完全是你的,并且不是你暴露给外部调用者的库的一部分(他们可以以不同的方式使用它)给你)。没有必要引入自定义调试器显示和自定义对象渲染的复杂性,除非这些实际上解决了无法以更简单和更直接的方式解决的问题。
答案 1 :(得分:1)
我远离ToString()
;即使这是一种记录自定义信息的低级仪式方式,它也会将对表示问题添加到对象中,这些问题将由日志记录消耗。由于日志记录是一个与对象存在的系统完全分离的系统,因此您要对已有对象的对象添加责任。提示SRP小提琴
从你的问题中,你所说的是两个需要更多信息的课程;我认为在这种情况下使用String.Format
就足够了。它与ToString
方法一样简单快捷,因为它没有暴露给其他消费者,所以危险性较小。
如果更多的类需要根据对象类型记录自定义信息,那么可能需要专用机制。例如,要记录的类的IInformationExtractorFor<T>
接口将在自定义appender中解析;接口和类不会绑定到log4net,因此系统可以在其他记录器中重用。当然,这只有在需要时才会实施:)