首先,请记住T?
(when T
'sa struct) 实际上意味着Nullable<T>
.
现在,让我们编写一个简短的测试程序来复制它:
using System;
class Program
{
public static void Main(string[] args)
{
DateTime? x = new Program();
Console.ReadKey(true);
}
public static implicit operator DateTime(Program x)
{
return new DateTime();
}
}
现在看看它编译成什么(使用伟大的 dotPeek 反编译):
using System;
internal class Program
{
public Program()
{
base..ctor();
}
public static implicit operator DateTime(Program x)
{
return new DateTime();
}
public static void Main(string[] args)
{
DateTime? nullable = new DateTime?((DateTime) new Program());
Console.ReadKey(true);
}
}
事实上,dotPeek 在这里对我很好:它应该是一样的,但DateTime? nullable = new DateTime?((DateTime) new Program());
改为Nullable<DateTime> nullable = new Nullable<DateTime>((DateTime) new Program());
如您所见,编译器implicit
只是将转换转换为转换。explicit
我猜发生的是编译器首先认为[1]你不能制作Foo
a DateTime?
,因为 a)它不是引用类型,并且 b)它不是 a DateTime
。那么它可能会通过它的一些隐式运算符[2],并找到一个匹配DateTime
的。然后它意识到[1]你可以将 a 转换DateTime
为 a Nullable<DateTime>
,所以它会这样做。
:)
[1] : 不是很想,但不要迂腐。
[2] : Eric Lippert 对此有评论,解释了这一点。