为什么整数== null是C#中有效的布尔表达式?

Gui*_*rez 11 c# null boolean non-nullable

为什么integer == nullC#中的有效布尔表达式,如果integer(类型的变量int)不可为空?(我不是反对它,事实上我喜欢它,但我不知道它是可能的)

Jon*_*eet 19

虽然int它本身是不可空的,但是有一个隐式转换int?,可以空.

此时,如果结构体声明了==两侧具有相同类型的运算符,那么它也可以用于可空类型.

所以这不编译:

public struct Foo {}

class Test
{
    static void Main()
    {
        Foo x = new Foo();
        if (x == null)
        {
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

...但是如果你给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; }
}
Run Code Online (Sandbox Code Playgroud)

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

因此,上面表单的代码(Foo可以由任何非可空取代struct)具有MS C#5编译器的三种结果之一:

  • 警告CS0472(例如int)
  • 错误CS0019(不重载的自定义类型==)
  • 清理编译(超载的自定义类型==,包括GuidDateTime)

我不清楚为什么编译器会将某些"已知"类型与普通结构区别对待.编辑:正如Eric在评论中所指出的,这是C#编译器中的已知错误,希望在Roslyn中修复.

  • Re:目前尚不清楚为什么已知类型与用户定义的类型不同:它是一个bug,可能是我在C#3.0期间重构部分编译器时引入的.由于一些不明原因,即使我们已经了解它很长一段时间,但这个bug从来没有被修复过.我似乎记得我在离开之前把它固定在罗斯林,但我不记得了. (10认同)
  • 我还注意到,这是http://stackoverflow.com/questions/2177850/guid-null-should-not-be-allowed-by-the-compiler/2177971#2177971和http://stackoverflow.com的副本/ a / 1972317/88656 (2认同)