【发布时间】:2014-02-18 16:12:54
【问题描述】:
我发现我的程序有一个奇怪的行为,经过进一步分析,我发现我的 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。我不明白为什么它是空的。
我用谷歌搜索了这个问题 - Implicit casting of Null-Coalescing operator result - 的官方规范。
但是按照这个规范,我找不到“b”为空的原因:(也许我读错了,在这种情况下我为垃圾邮件道歉。
如果 A 存在且不是可空类型或引用类型,则会发生编译时错误。
...不是这样的。
如果 b 是动态表达式,则结果类型是动态的。在运行时,首先评估 a。如果 a 不为 null,则将 a 转换为动态,这将成为结果。否则,对 b 求值,这将成为结果。
...事实并非如此。
否则,如果 A 存在并且是可空类型,并且存在从 b 到 A0 的隐式转换,则结果类型为 A0。在运行时,首先评估 a。如果 a 不为 null,则将 a 解包为类型 A0,这将成为结果。否则,b 被求值并转换为 A0 类型,这就是结果。
...A 存在,不存在从 b 到 A0 的隐式转换。
否则,如果存在 A 并且存在从 b 到 A 的隐式转换,则结果类型为 A。在运行时,首先计算 a。如果 a 不为空,则 a 成为结果。否则,b 被求值并转换为 A 类型,这就是结果。
...A 存在,不存在从 b 到 A 的隐式转换。
否则,如果 b 具有 B 类型并且存在从 a 到 B 的隐式转换,则结果类型为 B。在运行时,首先计算 a。如果 a 不为空,则将 a 解包为 A0 类型(如果 A 存在且可为空)并转换为 B 类型,这将成为结果。否则,b 被评估并成为结果。
...b 具有 B 类型,并且存在从 a 到 B 的隐式转换。 a 被评估为 null。因此,b 应该被评估并且 b 应该是结果。
否则a和b不兼容,会出现编译时错误。 不会发生
请问我有什么遗漏吗?
【问题讨论】:
-
不应该重写操作符来工作吗?
-
非常有趣。请注意,如果您将最后一行更改为
B b = (B)a ?? new B();,即您在代码中“显式”编写隐式强制转换,则会有所不同。 -
@JeppeStigNielsen 你这样做是在强制转换发生在空检查之前,而不是之后。
-
@Servy 没错。我发现并写在我的答案中。
标签: c# null implicit-conversion