我是 log4net 和 log4j 的忠实粉丝 "format" API用于记录消息,如果未启用必要的日志级别,则可以避免在参数上调用 ToString() 的成本。
但有时我使用的一个或多个参数不是一个简单的对象,它需要以某种方式构造。例如,像这样:
logger.DebugFormat("Item {0} not found in {1}",
itemID,
string.Join(",", items.Select(i => <you get the idea>))
);
是否有一种技术可以封装第二个参数(Join 表达式),除非 DebugFormat 决定它应该被执行(就像它对第一个参数的 ToString 所做的那样),否则它不会被执行?
感觉 lambda 或 func 或其他东西应该可以在这里提供帮助,但我是 C# 的新手,我不能完全理解它。
最佳答案
您可以创建扩展方法或包装类,但要获得令人满意的语法并不容易,因为您希望一些参数(在您的示例中为 itemID
)被明确说明,而一些仅被解析如有必要。但是您不能将匿名函数作为object
传递。相反,我会使用另一种不需要扩展方法或包装器的解决方案。像这样创建类:
public sealed class Delayed {
private readonly Lazy<object> _lazy;
public Delayed(Func<object> func) {
_lazy = new Lazy<object>(func, false);
}
public override string ToString() {
var result = _lazy.Value;
return result != null ? result.ToString() : "";
}
}
它接受在构造函数中返回对象的函数,并且在调用 ToString()
之前不会调用此函数,如您所知,log4net 仅在必要时才调用该函数(如果启用了此类调试级别) .然后像这样使用:
logger.DebugFormat("Item {0} not found in {1}",
itemID,
new Delayed(() => string.Join(",", items.Select(i => <you get the idea>)))
);
关于c# - 有没有一种技术可以将 DebugFormat() 与构建起来很昂贵的参数一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47413934/