重载转换运算符的转换规则

本文关键字:转换 规则 运算符 重载 | 更新日期: 2023-09-27 17:58:17

给定以下代码:

using System;
namespace Test721
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(new A()); //prints 666
            Console.WriteLine(new B()); //prints 666
            Console.ReadLine();
        }
    }
    public class A
    {
        public static implicit operator int(A a)
        {
            return 666;
        }
    }
    public class B : A
    {
        public static implicit operator double(B b)
        {
            return 667;
        }
    }
}

结果与评论中的一样——两行都打印666。

我希望Console.WriteLine(new B());写667,而double过载Console.WriteLine

为什么会发生这种情况?

重载转换运算符的转换规则

这在3.5 C#语言规范的第7.4.3.4节中有介绍。这一节讨论过载解决以及在这个过程中如何考虑转换。适用线路为

如果存在从T1到T2的隐式转换,并且不存在从T2到T1的隐式转化,则C1是更好的转化。

在这种情况下,存在从Bint(T1)和double(T2)的隐式转换。存在从intdouble的隐式转换,但不是相反。因此,从Bint的隐式转换被认为是更好的并且获胜。

由于您没有指定将值强制转换到编译器的内容,因此正在执行

Console.WriteLine((int)(new B()));

你应该使用以下

Console.WriteLine((double)(new B()));