为什么递增 Nullable<int> 不会抛出异常?
Why doesn't incrementing Nullable<int> throw an exception?
你能解释一下,为什么 Console.WriteLine 写空行(Console.WriteLine(null)
给我编译错误)以及为什么没有 NullReferenceException(即使 a+=1
也不应该引发它)?
int? a = null;
a++; // Why there is not NullReferenceException?
Console.WriteLine(a); // Empty line
您正在观察提升运算符的效果。
来自 C# 5 规范的第 7.3.7 节:
Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:
- For the unary operators
+ ++ - -- ! ~
a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single ?
modifier to the operand and result types. The lifted operator produces a null value if the operand is null. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.
所以基本上,a++
在这种情况下是一个结果为 null
的表达式(作为 int?
)并且变量保持不变。
当你打电话时
Console.WriteLine(a);
它被装箱到 object
中,将其转换为空引用,打印为空行。
Jon 的回答是正确的,但我会添加一些额外的注释。
Why does Console.WriteLine(null)
give a compilation error?
Console.WriteLine
有19个重载,其中三个适用于null
:一个string
,一个char[]
和需要 object
的那个。 C# 无法确定您指的是这三个中的哪一个,因此会报错。 Console.WriteLine((object)null)
是合法的,因为现在很清楚了。
why does Console.WriteLine(a)
write an empty line?
a
为空 int?
。重载解析选择方法的 object
版本,因此 int?
被装箱到空引用。所以这和Console.WriteLine((object)null)
基本一样,都是写一个空行
Why there is not NullReferenceException
on the increment?
您担心的 null reference 在哪里? a
是一个 null int?
,它不是引用类型!请记住,可为 null 的值类型是 值类型 ,而不是 引用类型 ,因此不要指望它们具有引用语义,除非它们被装箱到引用类型。加法里面没有装箱
Are You incrementing null???
int? a = null;
a++;
这个语句只是意味着 null++
即 null+1.
根据本文档,可空类型可以表示其基础值类型的正确值范围,再加上一个额外的空 value.A 可空,发音为 "Nullable of Int32," 可以分配任何值 - 2147483648到2147483647,也可以赋空值
这里你递增null,那么它也会变成null值而不是0或任何其他整数。
Why it prints blank instead of error??
当您打印具有空值的可空类型时,它打印空白而不是错误,因为您正在打印变量,即内存位置的值。可能为 null 或任何整数。
但是当您尝试使用 Console.WriteLine(null)
打印 null 时,因为 null 不是变量,所以它不引用任何内存位置。因此它给出了错误 "NullReferenceException"
。
Then how can you print any integer using Console.WriteLine(2);
??
在这种情况下,2将在临时位置进入内存,指针指向该内存位置进行打印。
你能解释一下,为什么 Console.WriteLine 写空行(Console.WriteLine(null)
给我编译错误)以及为什么没有 NullReferenceException(即使 a+=1
也不应该引发它)?
int? a = null;
a++; // Why there is not NullReferenceException?
Console.WriteLine(a); // Empty line
您正在观察提升运算符的效果。
来自 C# 5 规范的第 7.3.7 节:
Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types. Lifted operators are constructed from predefined and user-defined operators that meet certain requirements, as described in the following:
- For the unary operators
+ ++ - -- ! ~
a lifted form of an operator exists if the operand and result types are both non-nullable value types. The lifted form is constructed by adding a single?
modifier to the operand and result types. The lifted operator produces a null value if the operand is null. Otherwise, the lifted operator unwraps the operand, applies the underlying operator, and wraps the result.
所以基本上,a++
在这种情况下是一个结果为 null
的表达式(作为 int?
)并且变量保持不变。
当你打电话时
Console.WriteLine(a);
它被装箱到 object
中,将其转换为空引用,打印为空行。
Jon 的回答是正确的,但我会添加一些额外的注释。
Why does
Console.WriteLine(null)
give a compilation error?
Console.WriteLine
有19个重载,其中三个适用于null
:一个string
,一个char[]
和需要 object
的那个。 C# 无法确定您指的是这三个中的哪一个,因此会报错。 Console.WriteLine((object)null)
是合法的,因为现在很清楚了。
why does
Console.WriteLine(a)
write an empty line?
a
为空 int?
。重载解析选择方法的 object
版本,因此 int?
被装箱到空引用。所以这和Console.WriteLine((object)null)
基本一样,都是写一个空行
Why there is not
NullReferenceException
on the increment?
您担心的 null reference 在哪里? a
是一个 null int?
,它不是引用类型!请记住,可为 null 的值类型是 值类型 ,而不是 引用类型 ,因此不要指望它们具有引用语义,除非它们被装箱到引用类型。加法里面没有装箱
Are You incrementing null???
int? a = null;
a++;
这个语句只是意味着 null++
即 null+1.
根据本文档,可空类型可以表示其基础值类型的正确值范围,再加上一个额外的空 value.A 可空,发音为 "Nullable of Int32," 可以分配任何值 - 2147483648到2147483647,也可以赋空值
这里你递增null,那么它也会变成null值而不是0或任何其他整数。
Why it prints blank instead of error??
当您打印具有空值的可空类型时,它打印空白而不是错误,因为您正在打印变量,即内存位置的值。可能为 null 或任何整数。
但是当您尝试使用 Console.WriteLine(null)
打印 null 时,因为 null 不是变量,所以它不引用任何内存位置。因此它给出了错误 "NullReferenceException"
。
Then how can you print any integer using
Console.WriteLine(2);
??
在这种情况下,2将在临时位置进入内存,指针指向该内存位置进行打印。