我有一个类BackgroundTask
,我设置了一个类,用于在事情发生时记录事件,例如任务完成时。例如,对于这种Success
情况,我称Log.Verbose("{Task} completed successfully", this);
我的默认值ToString()
包括进度,但对于已完成的任务,我们知道它是 100%,所以我想忽略它。我知道对于数字类型,您可以传入自定义格式说明符字符串(例如"{IntProperty:p5}"
,它将我的 int 呈现为带有 5 个小数位的百分比),并且我希望能够执行相同的操作,例如Log.Information("{Task:Name}", this)
,它将通过进入"Name"
我的ToString()
方法。
我尝试添加许多不同的方法,例如添加ToString()
's,(不接受任何内容、字符串、字符串和IFormatProvider
)、实现IFormattable
、强制字符串化等,但似乎没有任何效果。我可以看到 Serilog 正在正确解析我的格式字符串: ( PropertyBinder.cs
,ConstructNamedProperties()
第 111 行)
这个调用ConstructProperty()
只是忽略了Format
令牌的属性,这解释了为什么它被忽略,但我想知道是否有一种我没有想到的方法。
PS 是的,我知道我有几种选择,但我不想这样做:
- 使用自定义解构器或手动将属性拉出到匿名类型中 - 这实际上破坏了原始对象,这正是我不想要的(我仍然希望将原始值存储为属性)。例如
Log.Information("{Task}", new {Name = this.Name, Id = this.Id});
- 使用我自己的格式字符串手动调用
ToString()
- 与 (1) 相同,这会破坏原始文件,这意味着它不会与所有信息一起存储。例如Log.Information("{Task}", this.ToString("Custom Format"));
- 在我的对象上创建一个属性,就像
ToStringFormat
在将它传递给 Serilog 之前一样 - 这似乎是不好的做法,只会增加额外的混乱,更不用说并发问题了。例如this.Format = "Custom FOrmat"; Log.Information("{Task}", this);