c# – 不应该如果(1 == null)导致错误?
参见英文答案 >
How can an object not be compared to null?5个
> C# okay with comparing value types to null9个 Int32结构体不为==操作符定义运算符重载方法,所以为什么代码不会导致编译时间错误: if(1 == null) ... ; 解决方法
让我们一起回到这里.这个问题令人困惑,到目前为止这些答案并不十分清楚.
不,这是合法的,虽然愚蠢. 编译器如何处理像“==”这样的运算符?它通过应用重载分辨率算法来实现. 我们必须确定的第一件事是,这是一个“用户定义的”等号运算符还是“内置的”等号运算符.左侧是内置型.右侧根本没有类型.这些都不是用户定义的类型.因此,不会考虑用户定义的运算符.只会考虑内置运算符. 一旦我们知道,问题是“哪些内置的操作符将被考虑?”内置操作符在规范第7.10节中有描述.它们是int,uint,long,ulong,decimal,float,double,任何枚举类型,bool,char,object,string和任何委托类型的等式运算符. 值类型上的所有等式运算符也有一个“提升”的形式,取值为可空值. 我们现在必须确定哪些操作符适用.为适用,必须从双方到操作符的类型进行隐式转换. 没有从int到任何枚举类型,string或任何委托类型的隐式转换,所以这些都从考虑中消失. (没有从int到uint,ulong等的隐式转换,但由于这是一个字面的转换,因此存在从1到uint,ulong等的隐式转换) 没有从null到任何非可空值类型的隐式转换,所以这些都会消失. 这是怎么回事?那个操作符在对象上,int?long?,uint?,ulong?double?float?decimal?和char?剩余的可空类型. 我们现在必须确定哪些剩余适用的候选人中的哪一个是唯一的“最佳”操作符.如果运算符的操作数类型更具体,则运算符优于另一运算符. “对象”是最不具体的类型,因此被消除.清楚的是,每个可空的int都可以转换为nullable long,但并不是每个可空的long都可以转换为nullable int,因此可空的long比NULLable int要小.所以它被淘汰.我们继续以这种方式消除操作符. (在无符号类型的情况下,我们应用一个特殊规则,说如果int?和uint?都是选项,那么int?wins.) 我会给你细节的;最终该进程将可空的int作为唯一的最佳操作数类型. 因此,您的程序被解释为((int?)1 ==(int?)null),这显然是合法的,并且将永远是假的.
你是对的.这与什么有关系?编译器完全可以在没有它的情况下进行分析.我不明白你认为这个事实与你的问题的关系.事实是关于一种可以在类型上定义的方法,问题是关于重载分辨率如何选择一个提升的内置运算符.这两个不相关,因为“int”不是用户定义的类型. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |