结构化类和反向隐式转换

nur*_*chi 0 c# implicit-conversion

假设我有一个结构和一个具有相同成员的类:

using System;

class app
{
    static void Main()
    {
        foo f = new foo() { a  = 4, b = 7 };
        bar b = f;
        Console.WriteLine(b.a);
        Console.ReadKey();
    }

    struct foo
    {
        public int a { get; set; }
        public uint b { get; set; }
    }

    class bar
    {
        public int a { get; set; }
        public uint b { get; set; }

        public static implicit operator foo(bar b)
        {
            return b;
        }

        public static implicit operator bar(foo f)
        {
            return f;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

简而言之,成员是相同的,但是类定义了与struct之间的隐式转换方法.

即使我没有指定如何转换值,这段代码也很乐意编译.我的第一个想法是"成员名称/类型是相同的,所以编译器必须能够弄明白"......

...,但后来我将其中一个成员的返回类型更改intstring,并重命名为没有原始名称的痕迹,代码仍然编译正常.

请向我解释一下这种行为.(环境是否试图"复制"尽可能多的成员?)

我在VS 2017社区中使用最新的.Net框架

Dam*_*ver 7

这是一个不幸的情况.代码编译但没用:

public static implicit operator bar(foo f)
{
    return f;
}
Run Code Online (Sandbox Code Playgroud)

当编译器到达时return f;,它有效地说"我foo在这个返回语句中有一个,但我打算返回一个bar.嗯.那没关系,因为一些善良的灵魂提供了一个隐含的运算符转换foobar,我'我会在这里调用转换操作符".

与许多其他非预期递归1的情况一样,简单的情况很容易发现,并且编译器可能会变得足够聪明以发现它们,但是你会遇到一个任意的截止点,超过这个截止点就不可能发现无限的编译期间的递归2.并且不一致的错误/警告往往不受欢迎(语言不太可预测).

值得庆幸的是,像这样的代码从未倾向于生产,因为一旦测试开始,堆栈溢出就会被发现.


1某种程度上被许多人咬伤的常见问题是尝试以自身的方式实现一个属性而不是使用其支持字段,但这可能是一种较少遇到的情况,现在自动实现的属性更加正常.

2插入停止问题等的标准参考.