Mir*_*rek 6 c# null implicit-conversion
我发现了我的程序的一个奇怪的行为,经过进一步的分析,我发现在我的C#知识或其他地方可能存在错误.我相信这是我的错,但我无法在任何地方找到答案......
public class B
{
    public static implicit operator B(A values) 
    {
        return null; 
    }
}
public class A { }
public class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = a ?? new B();
        //b = null ... is it wrong that I expect b to be B() ?
    }
}
此代码中的变量"b"被计算为null.我不明白为什么它是null.
我用谷歌搜索并在这个问题中找到了一个响应- 使用官方规范隐式转换Null-Coalescing运算符结果.
但是按照这个规范,我找不到"b"为空的原因:(也许我读错了,在这种情况下我为垃圾邮件道歉.
如果A存在且不是可空类型或引用类型,则发生编译时错误.
......事实并非如此.
如果b是动态表达式,则结果类型是动态的.在运行时,首先评估a.如果a不为null,则a将转换为dynamic,这将成为结果.否则,评估b,结果成为结果.
......事实并非如此.
否则,如果A存在且是可空类型,并且存在从b到A0的隐式转换,则结果类型为A0.在运行时,首先评估a.如果a不为null,则打开a以键入A0,这将成为结果.否则,b被评估并转换为类型A0,这就成了结果.
...存在,从b到A0的隐式转换不存在.
否则,如果A存在且从b到A存在隐式转换,则结果类型为A.在运行时,首先计算a.如果a不为null,则a成为结果.否则,b被评估并转换为类型A,这就是结果.
...存在,从b到A的隐式转换不存在.
否则,如果b具有类型B并且从a到B存在隐式转换,则结果类型为B.在运行时,首先计算a.如果a不为null,则打开a以键入A0(如果A存在且可为空)并转换为类型B,这将成为结果.否则,b被评估并成为结果.
... b具有类型B,并且从a到B存在隐式转换.a被评估为null.因此,应评估b,结果应为b.
否则,a和b不兼容,并发生编译时错误.不会发生
我错过了什么吗?
为什么你期望null合并运算符返回new B()?a不为null,因此a ?? new B()计算结果为a.
现在我们知道a将返回,我们需要确定result(T)的类型以及是否需要转换a为T.
•否则,如果b具有类型B并且从a到B存在隐式转换,则结果类型为B.在运行时,首先计算a.如果a不为null,则打开a以键入A0(如果A存在且可为空)并转换为类型B,这将成为结果.否则,b被评估并成为结果.
从Ato到存在隐式转换B,B表达式的结果类型也是如此.这意味着a将隐含地投入B.你的隐式运算符返回null.
实际上,如果你写var b = a ?? new B();(注意var),你会看到编译器推断B为表达式返回的类型.
好吧,规范说(我在这里更改为x和 ,y以减少混淆):
\n\n\n\xe2\x80\xa2 否则,如果 y 具有类型 Y 并且存在从 x 到 Y 的隐式转换,则结果类型为 Y。在运行时,首先计算 x。如果 x 不为 null,则 x 将解包为类型 X0(如果 X 存在且可为空)并转换为类型 Y,这将成为结果。否则,计算 y 并成为结果。
\n
有时候是这样的。首先,检查左侧x,即。但它本身并不是这样。然后将使用左侧。然后运行隐式转换。其类型结果是...。anullnullBnull
请注意,这不同于:
\n\n    A a = new A();\n    B b = (B)a ?? new B();\n在这种情况下,左操作数是一个表达式 ( x),它null本身就是一个表达式 ( ),结果成为右侧 ( y)。
也许引用类型之间的隐式转换应该返回null(如果并且)仅当原始类型是 时null,作为一个好的实践?
我想编写规范的人可以这样做(但没有):
\n\n\n\n\n\xe2\x80\xa2 否则,如果 y 具有类型 Y 并且存在从 x 到 Y 的隐式转换,则结果类型为 Y。在运行时,首先计算 x 并将其转换为类型 Y。如果该输出conversion 不为 null,输出即为结果。否则,计算 y 并成为结果。
\n
也许这样会更直观?无论转换的输入是否存在,它都会强制运行时调用隐式转换null。如果典型的实现能够快速确定这一点,那么成本应该不会太高null \xe2\x86\x92 null。
| 归档时间: | 
 | 
| 查看次数: | 1109 次 | 
| 最近记录: |