如何让插值字符串默认调用FormattableString参数的重载无需强制转换
解决方案
问题根源
C# 规范中插值字符串字面量的默认隐式转换优先级为 string > FormattableString,因此编译器在重载决策时会优先选择接收 string 的重载,导致插值字符串在进入日志方法前就被格式化为普通字符串,可能触发OOM异常,不符合需求。
最优实现方案
通过调整string参数重载的优先级即可实现自动匹配,不需要修改任何调用代码,也不需要逐处添加强制转换:
给接收string的重载增加一个无意义的可选参数,降低其重载优先级,这样插值字符串会自动匹配无额外参数的FormattableString重载,而普通字符串仍能正常匹配string重载。
示例代码
class Logger { // 增加无意义的可选参数,降低该重载的优先级 public static void Log(string s, bool ignore = default) { Console.WriteLine("It's a string"); } public static void Log(FormattableString s) { // 所有格式化逻辑放在内部执行,捕获所有异常 try { string result = s.ToString(); Console.WriteLine($"It's an interpolated string: {result}"); } catch { // 吞掉所有异常,包括OutOfMemoryException,符合日志器不抛异常的要求 // 可按需添加降级逻辑,比如仅输出插值字符串的常量部分 } } }
调用测试
Logger.Log("1 string"); // 正常命中string重载,输出"It's a string" Logger.Log($"{1+1} interpolated string"); // 自动命中FormattableString重载,无需强转
其他可选方案
如果不希望修改原有string重载的签名,可以单独新增一个专用于插值字符串的方法,比如命名为LogInterpolated,调用时使用该方法即可,也不需要强制转换。
内容的提问来源于stack exchange,提问作者Cristian Diaconescu
相关产品推荐
相关产品推荐

