> C# okay with comparing value types to null9个
Int32结构体不为==操作符定义运算符重载方法,所以为什么代码不会导致编译时间错误:
if(1 == null) ... ;
解决方法
Shouldn’t
if(1 == null)
cause an error?@H_502_14@
不,这是合法的,虽然愚蠢.@H_502_14@
编译器如何处理像“==”这样的运算符?它通过应用重载分辨率算法来实现.@H_502_14@
我们必须确定的第一件事是,这是一个“用户定义的”等号运算符还是“内置的”等号运算符.左侧是内置型.右侧根本没有类型.这些都不是用户定义的类型.因此,不会考虑用户定义的运算符.只会考虑内置运算符.@H_502_14@
一旦我们知道,问题是“哪些内置的操作符将被考虑?”内置操作符在规范第7.10节中有描述.它们是int,uint,long,ulong,decimal,float,double,任何枚举类型,bool,char,object,string和任何委托类型的等式运算符.@H_502_14@
值类型上的所有等式运算符也有一个“提升”的形式,取值为可空值.@H_502_14@
我们现在必须确定哪些操作符适用.为适用,必须从双方到操作符的类型进行隐式转换.@H_502_14@
没有从int到任何枚举类型,string或任何委托类型的隐式转换,所以这些都从考虑中消失.@H_502_14@
(没有从int到uint,ulong等的隐式转换,但由于这是一个字面的转换,因此存在从1到uint,ulong等的隐式转换)@H_502_14@
没有从null到任何非可空值类型的隐式转换,所以这些都会消失.@H_502_14@
这是怎么回事?那个操作符在对象上,int?long?,uint?,ulong?double?float?decimal?和char?剩余的可空类型.@H_502_14@
我们现在必须确定哪些剩余适用的候选人中的哪一个是唯一的“最佳”操作符.如果运算符的操作数类型更具体,则运算符优于另一运算符. “对象”是最不具体的类型,因此被消除.清楚的是,每个可空的int都可以转换为nullable long,但并不是每个可空的long都可以转换为nullable int,因此可空的long比NULLable int要小.所以它被淘汰.我们继续以这种方式消除操作符. (在无符号类型的情况下,我们应用一个特殊规则,说如果int?和uint?都是选项,那么int?wins.)@H_502_14@
我会给你细节的;最终该进程将可空的int作为唯一的最佳操作数类型.@H_502_14@
因此,您的程序被解释为((int?)1 ==(int?)null),这显然是合法的,并且将永远是假的.@H_502_14@
Int32 struct doesn’t define operator overload method for == operator@H_502_14@
你是对的.这与什么有关系?编译器完全可以在没有它的情况下进行分析.我不明白你认为这个事实与你的问题的关系.事实是关于一种可以在类型上定义的方法,问题是关于重载分辨率如何选择一个提升的内置运算符.这两个不相关,因为“int”不是用户定义的类型.@H_502_14@