1

我有一些 C# 类,MyChar、Myint、MyDouble,它们包装了 char、int 和 double。每个都有一个从包装类型到用户定义类型的隐式转换运算符。我还有一组重载函数,ToString(MyChar)、ToString(MyInt)、ToString(MyDouble)。

我想通过传入一个文字字符值来调用 ToString(MyChar),例如“A”。但编译失败并出现 CS0121,“以下方法或属性之间的调用不明确:'ToString(MyChar)' 和 'ToString(MyInt)'”。如果我传入一个 int 值,我会遇到类似的问题。

    public class MyChar
    {
        private MyChar(char val) => Value = val;
        public static implicit operator MyChar(char val) => new MyChar(val);
        public char Value { get; }
    }
    public class MyInt
    {
        private MyInt(int val) => Value = val;
        public static implicit operator MyInt(int val) => new MyInt(val);
        public int Value { get; }
    }
    public class MyDouble
    {
        private MyDouble(double val) => Value = val;
        public static implicit operator MyDouble(double val) => new MyDouble(val);
        public double Value { get; }
    }

    public class ConversionTests
    {
        public void DoIt()
        {
            Console.WriteLine(ToString('A')); // CS0121
            Console.WriteLine(ToString(1)); // CS0121
        }

        private static string ToString(MyChar c) => $"{c.Value}";
        private static string ToString(MyInt i) => $"{i.Value}";
        private static string ToString(MyDouble d) => $"{d.Value}";
    }

我发现通过添加从 MyInt 到 MyDouble 的隐式转换,我可以使编译器正确接受 int 值

    public class MyDouble
    {
        private MyDouble(double val) => Value = val;
        public static implicit operator MyDouble(double val) => new MyDouble(val);
        public static implicit operator MyDouble(MyInt val) => new MyDouble(val.Value);
        public double Value { get; }
    }
...
        public void DoIt()
        {
            Console.WriteLine(ToString('A')); // CS0121
            Console.WriteLine(ToString(1)); // now compiles :-)
        }

我想这是可行的,因为解析机制现在认为到 MyDouble 的转换现在是通过路线 1 -> MyInt -> MyDouble 进行的,并且这不能隐式发生,因为它需要两个用户定义的转换。同样,我可以ToString('A')通过添加另外两个隐式转换来正确解析:MyChar 到 MyDouble,以及 MyChar 到 MyInt。

这很好,因为它反映了 char、int 和 double 之间发生的隐式转换。但是谁能向我解释为什么上面发布的原始代码在没有额外转换的情况下无法编译,就像我这样的简单大脑可能理解的方式?

4

1 回答 1

0

Achar可以隐式转换为 a int。Anint可以隐式转换为double。鉴于类型的隐式转换My,这意味着ToString('A')可以由两种 ToString方法处理。

您可以删除所有ToString()方法ToString(MyInt),但代码仍然可以工作:

    public class ConversionTests
    {
        public void DoIt()
        {
            Console.WriteLine(ToString('A')); 
            Console.WriteLine(ToString(1));
        }

        private static string ToString(MyInt i) => $"{i.Value}";
    }

这将打印:

65
1
于 2021-10-20T11:27:52.953 回答