我正在尝试学习null条件运算符。从我学到的书中,例如,如果我将string []数组传递给方法,我可以代替使用条件范围,使用空条件运算符来检查传递的string []数组是否为空,因为例如在方法中我会想要使用.Length属性,如果我向它传递null,它将导致运行时错误。
我理解的所有这些,但是当我想使用来自通用Nullable结构的nullable int和.Value属性时,它已经在我身上抛出了编译错误。
我认为问题是,我不明白这是什么'?'在后缀变量之后做的是null。我认为它只是跳过它之后的属性或方法,但也许它传递null并且只是隐藏异常。我真的不知道,所以我想更深入地问这个Null条件运算符到底是什么,为什么这个可以为空的int示例导致错误。
错误代码:
class Program
{
static void Main(string[] args)
{
string text = null;
Console.WriteLine("Variable contains: {0}", text?.Length); //All OK
int? nullableInt = null;
Console.WriteLine("Variable contains: {0}", nullableInt?.Value); //Compiler error
Console.ReadLine();
}
}
修改: CompilerError消息:
'int'不包含'Value'的定义,并且没有扩展方法'Value'可以找到接受类型'int'的第一个参数(你是否缺少using指令或汇编引用?)
EDIT2: 这篇文章是重复的: null conditional operator not working with nullable types? 但是我无法理解这篇文章中的问题,但是我得到了@adjan的帖子 https://stackoverflow.com/a/44613674/7477611 在那里他解释得很好,但在我试图学习它的过程中,我为一个稍后会读到这个的人做了一个更好的解释,也许是为了和我一样处于同一个位置的人。
如果在可空类型上使用'?'运算符,例如int?.Member(Member - some method,property ...),则if if变量为null,它会跳过成员,但如果它有值,例如5,然后运算符'?'返回variable.GetValueOrDefault(),它只返回int值。 (返回Nullable的底层类型),这几乎是@adjan所说的。但是我将在这里介绍代码,为我解释了一切:
static void Main(string[] args)
{
int? number = null;
variable?.Member
// in fact operator '?' is doing folowing:
if (number.HasValue)
{
Console.WriteLine(number.GetValueOrDefault().GetType()); //System.Int32
}
else
{
Console.WriteLine(number); //null
}
}
正如您所看到的,number.GetValueOrDefault()返回System.Int32数据类型,如果您想使用.Value属性,则它必须是Nullable类型,而System.Int32不是可空类型,因此它无法访问.Value会员。这就是它导致错误的原因。
希望有帮助:) 谢谢您的回答。 :)
答案 0 :(得分:7)
值类型html
的可空类型上的variable?.Member
实际上转换为大致类似
T
if (variable.HasValue)
return variable.GetValueOrDefault().Member;
else
return null;
的类型为variable.GetValueOrDefault()
,而不是T
。只有Nullable<T>
有一个成员Nullable<T>
(除非它是您自己的包含成员Value
的结构,但例如代码中的Value
没有。)
答案 1 :(得分:2)
nullableInt?.Something
是语法糖:
nullableInt is null ? null : nullableInt.Value.Something
因此没有必要将.Value放在那里。如果你这样做,你实际上在做nullableInt.Value.Value
nullableInt?.Value
所需要的等效代码为nullableInt
(单独)。
另见:
答案 2 :(得分:0)
在您的代码中,您尝试访问Value
的成员nullableInt
,但由于此成员不存在,因此无法编译此代码。
?.
运营商是一个访问者。如果访问的成员存在且未设置或设置为null
,则它在运行时返回null
。相比之下,标准访问器(。)将在此方案中引发Null reference exception
。
尝试使用nullableInt ?? 0
之类的代码替换您的代码。 ??是null-coalescing运算符,并将用空字符串替换null。
答案 3 :(得分:0)
可空值类型是特殊类型。当您使用nullableInt?
时,您的结果实际上是int
类型,其中没有Value
属性。
Null条件运算符仅对引用类型和string
有意义,作为不可变引用类型的特例。
答案 4 :(得分:0)
以下代码说明了问题:
string[] temp = null;
int cc = -1;
if (temp == null)
{
cc = 0;
}
else
{
cc = temp.Count();
}
空数组(count()= 0)和数组为空。
您的代码变为:
Console.WriteLine("Variable contains: {0}", args?.Count() ?? 0); //All OK
Console.WriteLine("Variable contains: {0}", nullableInt?.ToString() ?? "woops"); //now ok