【发布时间】:2020-03-20 16:41:17
【问题描述】:
我基本上想要两个单独的 string/FormattableString 重载(背景是我想推动人们对日志消息使用字符串常量并通过结构化日志而不是日志消息传递参数以简化分析。所以 FormattableString 日志记录方法将被淘汰)。
现在由于编译器的工作方式,您不能直接重载方法,因为 FormattableString 在传递之前会演变为字符串。但是,有一个定义隐式重载的包装器结构是有效的:
public struct StringIfNotFormattableStringAdapter
{
public string StringValue { get; }
private StringIfNotFormattableStringAdapter(string s)
{
StringValue = s;
}
public static implicit operator StringIfNotFormattableStringAdapter(string s)
{
return new StringIfNotFormattableStringAdapter(s);
}
public static implicit operator StringIfNotFormattableStringAdapter(FormattableString fs)
{
throw new InvalidOperationException("This only exists to allow correct overload resolution. " +
"This should never be called since the FormattableString overload should be preferred to this.");
}
}
public static class Test
{
public static void Log(StringIfNotFormattableStringAdapter msg)
{
}
public static void Log(FormattableString msg)
{
}
public static void Foo()
{
Log("Hello"); // resolves to StringIfNotFormattableStringAdapter overload
Log($"Hello"); // resolves to FormattableString overload
}
}
到目前为止一切顺利。
我不明白的地方:为什么要删除
implicit operator StringIfNotFormattableStringAdapter(FormattableString fs)
导致呼叫Log($"Hello") 变得模棱两可?
CS0121 以下方法或属性之间的调用不明确:Test.Log(StringIfNotFormattableStringAdapter)' 和 'Test.Log(FormattableString)'`
【问题讨论】:
-
@PEterE 是的,我过去曾为某些事情编写过自定义分析器。我们有自己的 nlog 包装器,因此现有的分析器无法工作。与简单的带注释的重载相比,编写分析器需要更多的工作和更难维护。但是是的,这也可以,并且可以捕获更多的东西。
标签: c# language-lawyer overload-resolution