为什么我不能将泛型列表声明为可以为null

本文关键字:null 声明 列表 不能 泛型 为什么 | 更新日期: 2023-09-27 18:08:39

我正在尝试使用以下代码:

private Nullable<List<IpAddressRange>> ipAddressRangeToBind;

但我收到以下警告:

类型List必须是中不可为null的值类型以便将其用作泛型类型或方法中的参数"T"System.Nullable".

为什么我不能将泛型列表声明为可以为null

List<T>已经是引用类型(对于任何类型的T(-您只能声明Nullable<T>,其中T是不可为null的值类型(声明为Nullable<T> where T : struct(。

但这没关系,因为如果你只是声明:

private List<IpAddressRange> ipAddressRangeToBind;

那么你仍然可以有

ipAddressRangeToBind = null;

因为引用类型总是可以为null。

List<IpAddressRange>是一个引用类型-它已经可以为null了-事实上,它将被该声明初始化为null。

您可以直接使用它:

List<IpAddressRange> ipAddressRangeToBind = null;  

列表已可以为null。

由于泛型上的where T : struct约束,引用类型无法包装在Nullable<T>中。

这种限制的原因是:

  1. 根据定义,引用类型已经可以为null,并且
  2. 可为null不是很节省空间,但更多的是一种"逻辑"的可为null性

Nullable<T>具有布尔属性HasValue和包含实际值类型值的类型T属性Value

即使是HasValue == false(也就是说,如果可为null的包装变量设置为null(,您仍然会消耗值类型的空间,就好像它在那里一样。

它在逻辑上是可以为null的,允许您指定可选的行为,但它不会节省任何空间。这与boost::optional在C++中的工作方式非常相似。