C#Bug还是Brain Teaser?仅使用Coalesce(??)运算符进行转换

时间:2010-05-27 00:19:18

标签: c# .net casting

这很奇怪,也许有人可以解释发生了什么,或者这是一个错误(虽然我倾向于认为这可能只是关于C#的错综复杂的东西)。

以下代码抛出错误“无法隐式转换类型'uint?' 'uint'。“:

public void Test(UInt32? p)
{ 
    UInt32 x = p;
}

但是,此代码可以正常运行:

public void Test(UInt32? p)
{
    UInt32 x = p ?? 1;
}

咦?为什么这样做?为什么coalesce运算符会导致UInt32的隐式转换? (可为空)到UInt32(不可为空),而第一条错误消息表明这些类型之间没有隐式转换?

2 个答案:

答案 0 :(得分:11)

这样想。

Nullable<T>是一种值类型。显然,它不能真正为空。因此,表达式:

p == null

这真的是语法糖:

!p.HasValue

同样,表达式:

p ?? 1

是语法糖:

p.HasValue ? p.Value : 1

从前面的内容可以看出,表达式 p ?? 1实际上正在评估uint,这就是代码在没有强制转换的情况下工作的原因。

答案 1 :(得分:1)

合并运算符??起作用,因为C#编译器的可空类型explicit support位于运算符的左侧。正如丹涛所解释的那样,很明显,这种表达永远不会抛出异常。

查看Nullable<T>类型上的可用运算符,没有任何一项可以使p ?? 1int val = p更合法。它只能起作用,因为它是一个编译器功能。