C# 编译器错误:允许从 Nullable<decimal> 转换为十进制

vid*_*jot 1 c# operator-overloading type-conversion compiler-bug

考虑以下代码:

    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!
    }
Run Code Online (Sandbox Code Playgroud)

我根本不希望它编译,因为没有从十进制隐式转换?到十进制。

我认为这是一个错误还是我做错了什么?

我已经看到了这一点: 从 int 提升/可空转换的严重错误,允许从十进制转换

但这看起来不一样,而且已经过时了(7 年以上),所以现在应该修复错误,但无法确定,因为所有指向错误报告的链接都消失了)... :(

我真的很想在真正的解决方案中使用这样的代码(跟踪计算),但这阻止了我。

PS:我在 Windows 上编译。

Gur*_*ron 5

根据规范,提升转换运算符只允许用于值类型到值类型的转换(及其可为空的对应物),但在 Roslyn 编译器源代码中,您可以找到下一条评论:

故意违反规范:
即使转换的返回类型不是不可为空的值类型,本机编译器也允许“提升”转换。例如,如果我们有从转换struct Sstring,然后从“解禁”转换S?string由本地编译器视为存在,用的语义"s.HasValue ? (string)s.Value : (string)null"。为了向后兼容,Roslyn 编译器会保留此错误。

所以这似乎是一个实际的错误,它是为了向后兼容而引入的。而反编译正好说明了这种行为。