【问题标题】:Order of implicit conversions in c#c#中的隐式转换顺序
【发布时间】:2018-12-04 14:32:25
【问题描述】:

当 x 是来自用户定义类的对象时,在 Console.WriteLine(x) 中完成的隐式转换的顺序是什么:

    class Vector
    {
        public int x = 12;       

        public static implicit operator double(Vector v1)
        {
            return 3.14;
        }

        public static implicit operator int(Vector v1)
        {
            return 42;
        }

        public override string ToString()
        {
            return this.x.ToString();
        }

    }

    static void Main(string[] args)
    {
        Vector v11 = new Vector();
        Console.WriteLine(v11);
    }

为什么我得到 42,而不是 3.14 或“12”?为什么我不能向字符串添加额外的隐式转换/CW(int) 和 CW(string)/ 之间的歧义存在编译器错误:

        public static implicit operator string(Vector v1)
        {
            return "42";
        }

我知道我应该避免使用隐式转换,但只是出于好奇!

【问题讨论】:

  • 不,它打印 42(Visual Studio 2017 社区版的全新安装)
  • 我将假设它返回42,因为v11.xint,而不是doublestring,并且当v11 用于@987654331 时@,它调用VectorToString()方法,它调用v11.x.ToString()。如果我错了,请纠正我。
  • C# 重载解析是规范中最有趣的部分!我所说的“有趣”是指“当你开始做它并希望做你想做的事情时非常复杂,这样你就不必深入研究细节”。对于very specific interpretation of "better",采用intConsole.WriteLine 重载被认为“更好”。我还没有通过它来获得确切的细节。如果 Eric Lippert 有时间,他会出现并解释。 :-)
  • 这激起了我的好奇心,所以我去找Does implicit operator have higher priority over ToString() method? - 答案是肯定的。
  • 事实上,链接的问题不是重复的,因为这里没有明确调用ToString。为什么选择Console.WriteLine(int) 作为调用方法,而不是(比如)Console.WriteLine(double),这个问题没有得到另一个问题的回答,也没有为什么添加另一个转换会产生歧义。许多有趣的是重载解析和转换引起的问题,但它们并不完全相同。

标签: c# implicit-conversion


【解决方案1】:

所以打印的内容完全取决于选择了Console.WriteLine 的重载。选择哪个重载基于函数成员的“更好”规范的第 7.5.3.2 节。

当一个重载的参数比另一个“更具体”时,它比另一个“更好”。 “更具体”意味着存在从更具体的类型到不太具体的类型的隐式转换,并且没有从不太具体的类型到更具体的类型的隐式转换。

object 是最不具体的重载,因为没有从它到 int、double 或 string 的隐式转换,但每种类型都有一个。 int 比 double 更具体,因为存在从 int 到 double 的隐式转换,但没有从 double 到 int 的转换。 int 和 string 之间没有隐式转换,因此两者都不是更具体的,因此两者都没有比另一个更好或更差。

因此,如果存在从您的对象到 string 的隐式转换,则会考虑字符串重载,并且“最佳”重载存在平局,您会收到错误消息。当它丢失时,所有考虑的重载都有一个“最具体”的类型(即int),所以它是“最好的”,并且选择了这个重载。

【讨论】:

    猜你喜欢
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    相关资源
    最近更新 更多