I have a class BackgroundTask that I have set up to log events when things happen, such as when the task completes. For example, for the Success case, I call Log.Verbose("{Task} completed successfully", this); My default ToString() includes the progress, but for a completed task we know it's 100% so I would like to ignore it. I know that with numeric types you can pass in a custom format specifier string (like "{IntProperty:p5}", which would render my int as a percentage with 5 decimal places), and I would like to be able to do the same, such as Log.Information("{Task:Name}", this), which would pass in "Name" into my ToString() method.
I've tried adding lots of different methods like adding ToString()'s, (taking in nothing, a string, a string and IFormatProvider), implementing IFormattable, forcing stringification etc and nothing seems to work. I can see that Serilog is correctly parsing my format string: (PropertyBinder.cs, ConstructNamedProperties() line 111)

This calls ConstructProperty() which just ignores the Format property of the token, which explains why it's being ignored, but I was wondering if there was a way that would work that I haven't thought of.
PS Yes I'm aware I have several options I could do, but I'd rather not do these:
- Use a custom destructurer or manually pulling out the properties myself into an anonymous type - This essentially destroys the original object, which is exactly what I don't want (I still want the original value stored as a property). E.g.
Log.Information("{Task}", new {Name = this.Name, Id = this.Id}); - Manually call
ToString()with my own format string - Same as (1), this destroys the original, and means it won't be stored with all it's information. E.g.Log.Information("{Task}", this.ToString("Custom Format")); - Create a property on my object like
ToStringFormatbefore passing it into Serilog - This seems bad practice and just adds extra clutter, not to mention the concurrency issues. E.g.this.Format = "Custom FOrmat"; Log.Information("{Task}", this);