我看到这样的代码,并且我将其理解为使数组可为空,但是我不明白为什么我们需要它,因为数组是ref类型,因此它们已经可以为空。
所以,我的问题是为什么我们需要这个?
private readonly decimal?[] _amounts = new decimal?[_count];
答案 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分配给持有对该数组引用的变量。