4

Nullable micro-optimizations, part one中,Eric 提到它Nullable<T>有一种奇怪的装箱行为,这是类似的用户定义类型无法实现的。

C# 语言赋予预定义Nullable<T>类型的特殊功能是什么?尤其是那些不能在一个MyNullable类型上工作的。

当然,Nullable<T>有特殊的语法糖T?,但我的问题更多是关于语义的。

4

3 回答 3

11

我的意思是:没有盒装的 nullable 之类的东西。当你装箱时int,你会得到一个装箱的引用int。当您装箱时int?,您将获得空引用或对装箱的引用int。你永远不会得到一个盒装的int?.

您可以轻松地制作自己的Optional<T>结构,但不能实现具有这种装箱行为的结构。Nullable<T>的特殊行为已融入运行时。

这一事实导致了许多奇怪的事情。例如:

仅供参考,还有其他方式可以使Nullable<T>类型“神奇”。例如,虽然它是一个结构类型,但它不满足结构约束。您无法制作具有该属性的自己的结构。

于 2012-12-20T20:58:01.573 回答
2

我在C# 规范中找到了这两个:

  • 运算符的is工作方式T?与对 的作用相同T,并且as运算符可以转换为可为空的类型。
  • 对不可为空值类型进行操作的预定义和用户定义运算符被提升为这些类型的可空形式。

现在,以下是我认为不限于以下功能Nullable<T>

  • a 中的值switch可以是可为空的类型。我不认为这很重要,因为 switch 还接受可以在 MyNullable 类型上定义的用户定义的隐式转换。
  • 支持空 IDisposable 类型,在生成的 Dispose() 调用之前插入空检查。我不认为这很重要,因为我可以将 MyNullable 定义为一个类,然后它会是一样的。

这是我不确定的:

  • 规范提到了装箱/拆箱和隐式/显式转换,但我不明白是否可以使用 MyNullable 实现相同的结果。
于 2012-12-20T20:53:25.690 回答
2

C# 提升了可空类型的运算符。例如:

int? SumNullableInts(int? a, int? b)
{
    return a + b;
}

你必须做很多反射工作MyNullable<T>来支持它,然后下面会编译,它不应该:

MyNullable<List<string>.Enumerator> SumNullableEnumerators(MyNullable<List<string>.Enumerator> a, MyNullable<List<string>.Enumerator> b)
{
    return a + b;
}
于 2012-12-20T20:59:34.353 回答