11

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

4

2 回答 2

19

尽管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可以替换为任何 non-nullable struct)具有 MS C# 5 编译器的三个结果之一:

  • 警告 CS0472(例如带有int
  • 错误 CS0019(不重载的自定义类型==
  • 干净的编译(重载的自定义类型==,包括Guidand DateTime

我不清楚为什么编译器将某些“已知”类型与普通结构不同地对待。编辑:正如 Eric 在评论中所指出的,这是 C# 编译器中的一个已知错误,希望在 Roslyn 中得到修复。

于 2013-06-18T21:49:03.370 回答
1

正如 Ed 提到的那样,有一个警告,但警告暗示了原因:int可以自动转换为int?,并且null是类型变量的有效值int?

于 2013-06-18T21:49:24.970 回答