C# 结构到类和后隐式转换

C# 结构到类和后隐式转换,c#,implicit-conversion,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 {

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

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;
        }
    }
}
简而言之,成员是相同的,但是类定义了与结构之间的隐式转换方法

尽管我没有指定如何转换这些值,但这段代码仍然可以按原样编译。我的第一个想法是“成员名称/类型相同,因此编译器必须能够找出它”

…,但随后我将成员的一个返回类型从
int
更改为
string
,并将其重命名,不留下原始名称的痕迹,代码仍然编译良好

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


我在VS 2017社区中使用了最新的.Net框架,这是一个不幸的情况。代码可以编译,但没有用处:

public static implicit operator bar(foo f)
{
    return f;
}
当编译器到达
时返回f
,它有效地表示“我在这个返回语句中得到了一个
foo
,但我要返回一个
bar
。嗯。这没关系,因为一些善良的灵魂提供了一个隐式操作符,可以将
foo
转换为
bar
,我在这里调用这个转换操作符”

与许多其他意外递归1的情况一样,简单的情况很容易发现,而且编译器可能会变得足够聪明来发现它们,但随后您会遇到一个任意的截止点,超过这个截止点,在编译过程中就不可能发现无限递归2。而且,不一致的错误/警告往往会受到反对(不太可预测的语言)

谢天谢地,像这样的代码永远不会进入生产环境,因为堆栈溢出往往在测试一开始就被发现


1在某些时候,让很多人感到痛苦的一个常见问题是,试图实现一个属性本身,而不是使用它的支持字段,但这可能是目前较少遇到的情况,因为自动实现的属性更为正常


2插入有关停止问题等的标准参考。

您是否尝试测试这些运算符?当您尝试从类转换为结构时发生了什么?我运行了您的代码,它不起作用。此站点的相应消息:-)System.StackOverflowException:“引发了类型为'System.StackOverflowException'的异常。可能是重复的谢谢。”。我不会想到这一点(如果我调试了其中的一行代码:P,我可能会想到)。这解释了Aldert在对我的问题的评论中提到的StackOverflowException。当重载
Equals
=
时,我遇到了类似的问题=运算符,只是没有将2和2放在一起。再次感谢您的精彩解释(特别是关于“某个善良的灵魂提供了一个隐式操作符…”:D)。