可空数组以及为什么需要它们

时间:2019-01-02 17:02:49

标签: c# arrays nullable

我看到这样的代码,并且我将其理解为使数组可为空,但是我不明白为什么我们需要它,因为数组是ref类型,因此它们已经可以为空。

所以,我的问题是为什么我们需要这个?

private readonly decimal?[] _amounts = new decimal?[_count];

4 个答案:

答案 0 :(得分:5)

将其声明为decimal?[]意味着数组包含的元素可以为null或非null

如果不使其成为 nullable ,则数组可以存储的元素不能为null

换句话说,decimal?[]读为“ 可空小数的数组”。 ?是指数组可以包含的元素,而不是数组本身,因为所有数组都是引用类型。

答案 1 :(得分:1)

此处的可为空的说明符不是指向数组本身,而是指向数组的内容。正确地说,数组本身是引用类型,因此始终是可操作的(至少直到C#8为止)。

一些区别的例子:

decimal[] nonNullable = new decimal[2];
nonNullable[0] = 1;             //OK, a non null item
nonNullable[1] = null;          //Compile error: array doesn't accepts nulls
nonNullable = null;             //OK, set the array reference to null

decimal?[] nullable = new decimal?[2];
nullable[0] = 1;                //OK, a non null item
nullable[1] = null;             //OK, a null item (actually, a Nullable<decimal> instance)
nullable = null;                //OK, set the array reference to null

答案 2 :(得分:1)

数组对象本身与数组元素之间存在差异。使用decimal?[]时,您要声明一个数组,其元素为可为空的decimal值。如果要使用decimal[]?(我不确定那是有效的语法,但仅出于解释目的,假设是这样),则将声明一个变量,该变量可能引用数组,也可能未引用任何东西。后者是您所描述的无用的情况,因为,就像您说的那样(至少在C#的较早版本中),所有数组变量都是可以设置为null的引用变量。

为澄清差异,请考虑Alejandro发布的代码以及以下代码:

decimal[]? reallyNullable = null;

Array.Sort(reallyNullable); // ArgumentNullException -- there is no array here
Array.Sort(nullable); // OK, assuming null can be compared to decimal.

最后一行没问题的原因是,实际上这里引用了一个数组对象。唯一为空的是其中的一些值。

答案 3 :(得分:1)

值得一提的是,在C#8.0中,您可以使用可空引用类型https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/nullable-reference-types 因为使用C#8.0引用类型,默认情况下不能为null(如果在项目中启用了此功能)。

但正如其他人提到的那样:

private readonly decimal?[] _amounts = new decimal?[_count];

表示数组中的value-type元素可以为null。 decimal是值类型,通常您不能为它加上null,但是如果您有decimal?,则可以。

启用C#8.0和可为空的引用类型功能后,如果要为它们设置null,则必须具有可为空的引用类型(显式声明)。您可以这样声明:

private decimal?[]? _amounts;

现在,这意味着数组中的两个元素都可以为null,整个数组(_amounts变量)可以为null。

因此,通常在元素值类型?之后和[] -> SomeValueType?[]之前的问号表示数组中的元素可以为null。从C#8.0(在项目中启用了功能)开始,在数组类型? SomeArrayType[] ->之后的问号SomeArrayType[]?意味着您可以将null分配给持有对该数组引用的变量。