Good day!
I'm experimenting with some logging features, in particular adding caller information for logging using interpolated strings. This is in Visual Studio 2022 using C# & .NET 6.0.
I'm trying to add the caller information (name, path, and line number) to the method:
public static void Log<T>(this T logLabel, [InterpolatedStringHandlerArgument("logLabel")] TraceLoggerParamsInterpolatedStringHandler handler) 
    where T : Enum
{
        ...
}
The dilemma is the caller information needs to occur before the handler for those arguments to be sent to the constructor of the TraceLoggerParamsInterpolatedStringHandler itself. However, because those attributes require those parameters to have default values, that means the handler requires a default value, too.
If I do:
public static void Log<T>(this T logLabel,
    [CallerMemberName] string callerName = "",
    [CallerFilePath] string callerFilePath = "",
    [CallerLineNumber] int callerLineNumber = -1,
    [InterpolatedStringHandlerArgument("logLabel", "callerName", "callerFilePath", "callerLineNumber")] TraceLoggerParamsInterpolatedStringHandler handler = default) 
    where T : Enum
{
        ...
}
Then the handler is initialized as the default, it doesn't call the specialized constructor that takes the additional parameters. I don't know if this is a code-gen issue in this case for interpolated strings.
Here is the disasm for the call site:
00007FF84DD2B2AF  call        Method stub for: System.Runtime.CompilerServices.DefaultInterpolatedStringHandler..ctor(Int32, Int32) (07FF84D6AC1B0h)  
00007FF84DD2B2B4  mov         rdx,260C53C4D68h  
00007FF84DD2B2BE  mov         rdx,qword ptr [rdx]  
00007FF84DD2B2C1  lea         rcx,[rbp+0A8h]  
00007FF84DD2B2C8  call        Method stub for: System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendLiteral(System.String) (07FF84D6AC1F8h)  
I'm suspecting however I'll just have to move those parameters after and pass them to the handler explicitly to work around this.
If there is a more elegant solution, I'd appreciate the insight!
Thank you,
Brent Scriver
                        
Turns out this is pretty simple: just add the various
[Caller...]arguments to yourInterpolatedStringHandlerconstructor itself. Like this:Then, you don't need the
[InterpolatedStringHandlerArguments]at all. Your method signature can just be:And you call it as expected:
The compiler, correctly, turns that into this:
And, by the way, this will still work if you actually do have to use [InterpolatedStringHandlerArgument] with extra arguments.