I have a logging scenario where two overloads are used, for string and for FormattableString:
class Logger
{
public static void Log(string s)
{
Console.WriteLine("It's a string");
}
public static void Log(FormattableString s)
{
Console.WriteLine("It's an interpolated string");
}
}
However, both these calls are directed at the string overload:
Logger.Log("1 string"); // => "It's a string"
Logger.Log($"{1+1} interpolated string"); // => "It's a string"
If I explicitly cast the interpolated string, it works.
Logger.Log((FormattableString)$"{1+1} interpolated string"); // => "It's an interpolated string"
Is there any way to get the FormattableString overload be called for the interpolated string, without having to add casts everywhere?
For a bit of context:
The logger must run without ever throwing exceptions.
In case of very high memory pressure, even an interpolated string (or rather, its materialization to a normal string) can throw OutOfMemoryException, because under the covers it calls string.Format() which uses a StringBuilder which does memory allocations:
var s = $"this is {1+1} interpolated"; //can throw OOM!
Calls looking like this must not throw:
Logger.Log($"interpolated {1+1}");
...so the materialization of the interpolated string must be deferred and handled inside the logger, and any exceptions swallowed.

