[英]Why does casting a null to a primitive(ie: int) in .net 2.0 throw a null ref exception and not a invalid cast exception?
[英].Net 2+: why does if( 1 == null ) no longer throw a compiler exception?
我以int
为例,但这适用于.Net 中的任何值类型
在.Net 1 中,以下会引发编译器异常:
int i = SomeFunctionThatReturnsInt();
if( i == null ) //compiler exception here
现在(in.Net 2 或 3.5)该异常已经消失。
我知道这是为什么:
int? j = null; //nullable int
if( i == j ) //this shouldn't throw an exception
问题是因为int?
可以为空并且int
现在隐式转换为int?
. 上面的语法是编译器的魔法。 我们真的在做:
Nullable<int> j = null; //nullable int
//compiler is smart enough to do this
if( (Nullable<int>) i == j)
//and not this
if( i == (int) j)
所以现在,当我们执行i == null
时,我们得到:
if( (Nullable<int>) i == null )
鉴于 C# 正在执行编译器逻辑来计算这个,为什么在处理像null
这样的绝对值时不能聪明到不这样做?
奇怪......用VS2008编译这个,针对.NET 3.5:
static int F()
{
return 42;
}
static void Main(string[] args)
{
int i = F();
if (i == null)
{
}
}
我收到编译器警告
warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
它会生成以下 IL ......据推测 JIT 会优化掉
L_0001: call int32 ConsoleApplication1.Program::F()
L_0006: stloc.0
L_0007: ldc.i4.0
L_0008: ldc.i4.0
L_0009: ceq
L_000b: stloc.1
L_000c: br.s L_000e
你能发布一个代码片段吗?
我认为这本身不是编译器问题; integer 值永远不会是 null,但将它们等同起来的想法并非无效; 这是一个有效的 function 总是返回 false。 编译器知道; 编码
bool oneIsNull = 1 == null;
编译,但给出编译器警告: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'
。
因此,如果您想要返回编译器错误,go 到项目属性并为此错误打开“将警告视为错误”,您将再次开始将它们视为构建中断问题。
当您将不可为空的类型与 null 进行比较时,编译器仍然会生成警告,这正是它应该的方式。 可能是您的警告级别太低或在最近的版本中已更改(我仅在 .net 3.5 中这样做)。
2.0 框架引入了可空值类型。 即使字面常量“1”永远不可能是 null,它的基础类型 (int) 现在可以转换为 Nullable int 类型。 我的猜测是编译器不能再假设 int 类型不可为空,即使它是一个字面常量。 编译 2.0 时确实收到警告:
警告 1 表达式的结果始终为“假”,因为“int”类型的值永远不会等于“int?”类型的“null”。
警告是新的(我认为是 3.5) - 错误与我所做的1 == 2
相同,它足够聪明,可以发现它永远不会正确。
我怀疑通过完整的 3.5 优化,整个语句将被删除,因为它非常聪明,从来没有真正的评估。
虽然我可能希望1==2
编译(例如,在我测试其他东西时关闭 function 块)我不希望1==null
。
这应该是编译时错误,因为类型不兼容(值类型永远不能为空)。 很遗憾,事实并非如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.