-
Type: Improvement
-
Resolution: Done
-
Priority: Unknown
-
Affects Version/s: None
-
Component/s: Logging
-
None
Interpolated strings are rendered immediately rather than captured. For example:
var greeting = "world"; var message = $"Hello, {greeting}!"; Log(() => message); void Log(Func<string> func) { Console.WriteLine(func()); }
The intent is to only render the string in the Log method if it is needed. However looking at the decompiled MSIL, we can see that the rendered message is passed into the lambda, not the format string and arguments:
using System; using System.Runtime.CompilerServices; [CompilerGenerated] internal class Program { private static void <Main>$(string[] args) { <>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0(); string greeting = "world"; CS$<>8__locals0.message = "Hello, " + greeting + "!"; Log(() => CS$<>8__locals0.message); [CompilerGenerated] static void Log(Func<string> func) { Console.WriteLine(func.Invoke()); } } }
We do this throughout our logging code. For example in DnsMonitor:
var message = $"Unhandled exception in DnsMonitor: {exception}."; var sdamInformationEvent = new SdamInformationEvent(() => message); _sdamInformationEventHandler(sdamInformationEvent);
We should change all usages of interpolated strings in logging to use the classic format string plus arguments approach to reduce the cost of logging when no listeners are configured.