为什么显式转换为'decimal'会将显式运算符调用为'long'?

Tim*_*mwi 16 c# implicit-conversion

请考虑以下代码:

class Program
{
    public static explicit operator long(Program x) { return 47; }

    static int Main(string[] args)
    {
        var x = new Program();
        Console.WriteLine((decimal) x);
    }
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,这个输出47; 换句话说,explicit operator long即使是演员也是如此decimal.

C#规范中是否有明确说明应该发生这种情况(如果是这样,究竟在哪里)或者这是否是我遗漏的其他一些规则的结果?

Kei*_*thS 6

我能想到的唯一解释是编译器足够聪明,可以实现有一个隐式运算符,它将long转换为十进制,当Program只能转换为long时,它可以用来满足Program和decimal之间的显式转换.

编辑:我们在这里; 数字类型之间的转换内置于语言规范中:

6.1.2隐式数字转换

隐式数字转换是:

·从sbyte到short,int,long,float,double或decimal.

·从byte到short,ushort,int,uint,long,ulong,float,double或decimal.

·从short到int,long,float,double或decimal.

·从ushort到int,uint,long,ulong,float,double或decimal.

·从int到long,float,double或decimal.

·从uint到long,ulong,float,double或decimal.

· 从long到float,double或decimal.

·从ulong到float,double或decimal.

·从char到ushort,int,uint,long,ulong,float,double或decimal.

·从浮动到双重.

从int,uint,long或ulong到float以及从long或ulong到double的转换可能会导致精度损失,但绝不会导致数量级的损失.其他隐式数字转换永远不会丢失任何信息.

char类型没有隐式转换,因此其他整数类型的值不会自动转换为char类型.

因此,在程序和十进制之间进行转换时,C#知道它可以隐式地从任何数字类型转换为十进制,因此在执行此显式转换时,它将查找可以将程序转换为数字类型的任何运算符.

有趣的是,如果您还将显式转换为uint,那么会返回48会发生什么?编译器选哪一个?

  • 如果是这种情况,我想知道规范的哪些部分允许...... (4认同)

Tim*_*mwi 6

我找到了答案.首先,有一种类型的概念被另一种类型所包含,在6.4.3用户定义的转换评估中定义如下:

如果从类型A到类型B存在标准隐式转换(第6.3.1节),并且如果A和B都不是接口类型,那么A被认为包含在 B中,并且B被认为包含 A.

6.3.1标准的隐式转换指出,"隐式数字转换(§6.1.2)"是一种标准的隐式转换,和6.1.2隐数值转换反过来定义了从隐式转换longdecimal.因此,long所涵盖 decimal.

接下来,6.4.5用户定义的显式转换表明确定显式转换是否适用的其中一个阶段是:

查找适用的用户定义和提升转换运算符集合U.此集合包含由D中的类或结构声明的用户定义和提升的隐式或显式转换运算符,这些运算符从包含或包含在S中的类型转换为T包含或包含T.如果U为空,则转换未定义,并发生编译时错误.

这里,D指的是较早步骤的结果,在这种情况下,仅包含decimal,Programobject.因此,该集U将包含我声明的Program-to- longexplicit运算符,因为long它包含在decimal(如前所述).

接下来的步骤之一选择long作为最具体的目标类型, TX.

最后,同一算法的最后一步说明:

最后,应用转换:

  • 如果S不是SX,则执行从S到SX的标准显式转换.
  • 调用最具体的用户定义转换运算符以从SX转换为TX.
  • 如果TX不是T,则执行从TX到T的标准显式转换.

在这里,S并且SX都是Program,所以第一部分什么都不做.TX被选择为longT为目标类型,decimal,所以最后部分执行从标准转换longdecimal.

  • 一切都非常有趣。感谢分享。我刚刚开始自己​​查看规范,所以你节省了我很多时间。;-) (2认同)