C# 在条件语句中使用null条件运算符时,如何处理null情况?
假设我在这里有以下代码:C# 在条件语句中使用null条件运算符时,如何处理null情况?,c#,.net,C#,.net,假设我在这里有以下代码: static void Main(string[] args) { StringBuilder[] s = new StringBuilder[3]; if (s[0]?.Length > 0) { Console.WriteLine("hi"); } } 我的理解是if语句中的表达式必须是布尔表达式。布尔表达式(我的理解可能是错误的)是计算结果为true或false的表达式 在这种情况下,null条件运算符将返回null,
static void Main(string[] args)
{
StringBuilder[] s = new StringBuilder[3];
if (s[0]?.Length > 0)
{
Console.WriteLine("hi");
}
}
我的理解是if语句中的表达式必须是布尔表达式。布尔表达式(我的理解可能是错误的)是计算结果为true或false的表达式
在这种情况下,null条件运算符将返回null,因为引用类型变量数组中元素的默认值为null。因此,这个if语句等价于
bool? x = null;
if (x)
{
// do cool things here */
}
但这给了我一个语法错误:无法将null转换为bool
因此,上面的StringBuilder示例如何工作?我的理解是,处理上述代码的更好方法应该是将其与空合并运算符相结合,如:
if (s[0]?.Length > 0 ?? false) {}
谢谢大家:)唉,我相信多点谷歌搜索就能给我一个答案! 这个问题帮助了我: 基本上,对于某些操作符(我相信,=),这些操作符被“提升”以处理null情况。如果这些二元运算符中的任何一个操作数为null,它们将自动返回false 比如说
int? x = 5;
int? y = 10;
bool b = x < y; // true
int?x=5;
智力?y=10;
布尔b=x
为什么这样做有效?因为它在语义上等同于:
bool b = (x.HasValue && y.HasValue) ? (x.Value < y.Value) : false;
bool b=(x.HasValue&&y.HasValue)?(x.Value
如果其中一个操作数没有值,则始终返回false
非常感谢 在你的声明中
if (x)
x
不是布尔表达式它是可为空的bool
。简而言之,您不能在if
语句中将不求值的语句放在布尔表达式中
但是,您可以通过指定true
或false
来Lifted
它,这利用了可为空的Lifted
运算符。例如
if (x == true)
//or
if (x == false)
类似地,提升是导致以下各项工作的原因
int? i = null;
if(i > 0) {...}
这也可以通过Null条件运算符看到
这里发生的是,Null条件强制将Length
(这是一个int
)解释为可为Null的int
,它会被检查为Null并提升到int
,以进行比较
注意:重新解释时实际生成的IL将如下所示
如果((object)obj==null | | obj.Length您的等价性是错误的
写入var x=s[0]?.Length>0;
与bool x=false
相同,而不是bool?x=null
产生的未优化IL为:
IL_0013: ldloc.0 // s
IL_0014: ldc.i4.0
IL_0015: ldelem.ref
IL_0016: dup
IL_0017: brtrue.s IL_001D
IL_0019: pop
IL_001A: ldc.i4.0
IL_001B: br.s IL_0025
IL_001D: call System.Text.StringBuilder.get_Length
IL_0022: ldc.i4.0
IL_0023: cgt
IL_0025: stloc.1 // x
我希望你已经回答了你的问题。对不起,但是“Length
(这是一个int
)被解释为可为空的int
”是不正确的。@Enigmativity对不起,我把评论搞乱了,无论如何我喜欢你的回答,upvote
if ((object)obj == null || obj.Length <= 0)
IL_0013: ldloc.0 // s
IL_0014: ldc.i4.0
IL_0015: ldelem.ref
IL_0016: dup
IL_0017: brtrue.s IL_001D
IL_0019: pop
IL_001A: ldc.i4.0
IL_001B: br.s IL_0025
IL_001D: call System.Text.StringBuilder.get_Length
IL_0022: ldc.i4.0
IL_0023: cgt
IL_0025: stloc.1 // x
StringBuilder[] array = new StringBuilder[3];
StringBuilder obj = array[0];
if (obj != null && obj.Length > 0)
{
Console.WriteLine("hi");
}