考虑以下代码:
public class DecimalWrapper
{
public static implicit operator DecimalWrapper(decimal x) => new();
}
[Fact]
public void Test()
{
// Why this even compiles? Since there is no implicit conversion from decimal? -> decimal
DecimalWrapper c = (decimal?)null; // variable 'c' is null!
}
我不期望它可以编译,因为没有从十进制的隐式转换?小数。
我认为这是一个bug还是我弄错了?
我看过这个:从int中移除/空转换的严重bug,允许从十进制
进行转换但是这个看起来不一样,它是旧的(7年以上),所以现在应该修复错误,但不能确定,因为所有的链接到错误报告都消失了)…(
我真的很想在实际解决方案中使用这样的代码(跟踪计算),但这阻止了我。
PS:我正在Windows上编译。
根据规范,提升的转换操作符只允许值类型到值类型的转换(以及它们的可空对应项),但在Roslyn编译器的源代码中,您可以找到下一个注释:
故意违反规范:
本机编译器允许使用"取消的";转换,即使转换的返回类型不是非空值类型。例如,如果我们有一个从struct S
到string
的转换,那么一个"提升";本机编译器认为存在从S?
到string
的转换,其语义为"s.HasValue ? (string)s.Value : (string)null"
。Roslyn编译器为了向后兼容而使这个错误永久存在。
所以它看起来是一个为了向后兼容而引入的bug。而反编译恰恰显示了这种行为。