为啥整数 == null 在 C# 中是一个有效的布尔表达式?

Posted

技术标签:

【中文标题】为啥整数 == null 在 C# 中是一个有效的布尔表达式?【英文标题】:Why is integer == null a valid boolean expression in C#?为什么整数 == null 在 C# 中是一个有效的布尔表达式? 【发布时间】:2013-06-15 07:05:55 【问题描述】:

如果integerint 类型的变量)不可为空,为什么 integer == null 在 C# 中是一个有效的布尔表达式? (我不反对,其实我很喜欢,但我不知道有可能)

【问题讨论】:

您确实会收到警告,类似于“表达式总是错误的”。至于为什么允许,即不会导致编译时错误……我想这与允许这样做的原因相同; while(true) C# 编译器将在编译时将其优化为在发布模式下编译时为 false(ldc.i4.0 最终在 IL 中)。 C# okay with comparing value types to null的可能重复 【参考方案1】:

虽然int 本身不可为空,但存在到int? 的隐式转换, 可以为空。

此时,如果该结构声明了一个两边都具有相同类型的 == 运算符,那么它也可以用于可空类型。

所以这不会编译:

public struct Foo 

class Test

    static void Main()
    
        Foo x = new Foo();
        if (x == null)
        
            ...
        
    

...但是如果你给Foo 一些运算符,它确实编译,并且没有警告:

public struct Foo

    public static bool operator ==(Foo x, Foo y)  return true; 
    public static bool operator !=(Foo x, Foo y)  return false; 
    public override bool Equals(object x)  return false; 
    public override int GetHashCode()  return 0; 

运算符调用不包含在编译代码中,因为编译器知道 RHS 为空。

因此,上述形式的代码(其中Foo 可以替换为任何不可为空的struct)在 MS C# 5 编译器中具有以下三种结果之一:

警告 CS0472(例如 int) 错误 CS0019(自定义类型不会重载 ==) 干净编译(重载==的自定义类型,包括GuidDateTime

我不清楚为什么编译器会以不同于普通结构的方式处理某些“已知”类型。编辑:正如 Eric 在 cmets 中所指出的,这是 C# 编译器中的一个已知错误,希望在 Roslyn 中得到修复。

【讨论】:

妈的,太奇怪了!也许结构是例外? 并尝试创建自己的隐式运算符以将其转换为Nullable<T>(例如public static implicit operator Nullable<Foo>(Foo f))失败并出现编译器错误CS0555。 回复:尚不清楚为什么已知类型与用户定义类型不同:这是一个错误,可能是我在 C# 3.0 期间重构部分编译器时引入的。由于某些不清楚的原因,该错误从未得到修复,即使我们已经知道很长时间了。我似乎记得我在离开之前在罗斯林修好了它,但我不记得了。 我还注意到这是***.com/questions/2177850/…和***.com/a/1972317/88656的副本 而这个也有一些类似的分析:***.com/questions/2464097/…【参考方案2】:

正如 Ed 提到的,有一个警告,但警告暗示了原因:int 可以自动转换为 int?,而nullint? 类型变量的有效值。

【讨论】:

skeet 秒杀我。该死的飞碟! 你说反了。您的意思是说int 可以隐式转换int? 确认。谢谢埃里克。已更正。

以上是关于为啥整数 == null 在 C# 中是一个有效的布尔表达式?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C# 编译器不抛出 null 的逻辑比较?

为啥使用 == 比较两个整数有时有效,有时无效? [复制]

为啥 var m = 6 + + + + + + + + 6;在c#中有效吗?

asp.net gridview 我绑上的值一个数值类型 库中是空值 在循环gridview 取值的时候为啥是“ ”请高手

C# bool 是原子的,为啥 volatile 有效

为啥 5.0/3 在 C 中是 1.666667?