c#“==”运算符:具有不同结构的编译器行为

时间:2010-04-19 05:38:34

标签: c# .net

代码说明:

    public struct MyStruct
    {
        public int SomeNumber;
    }

    public string DoSomethingWithMyStruct(MyStruct s)
    {
        if (s == null)
            return "this can't happen";
        else
            return "ok";
    }

    private string DoSomethingWithDateTime(DateTime s)
    {
        if (s == null)
            return "this can't happen";  // XX
        else
            return "ok";
    }

现在,“DoSomethingWithStruct”无法编译:“运算符'=='无法应用于'MyStruct'和'<null>''类型的操作数。这是有道理的,因为尝试与结构进行参考比较是没有意义的,结构是一种值类型。

OTOH,“DoSomethingWithDateTime”编译,但编译器警告:“检测到无法访问的代码”标记为“XX”的行。现在,我假设这里没有编译器错误,因为DateTime结构重载了“==”运算符。但编译器如何知道代码无法访问?例如它是否在重载“==”运算符的代码中查看? (这是使用Visual Studio 2005以防万一)。

注意:我对上述情况比任何事都更好奇。我通常不会尝试使用“==”来比较结构和空值。

编辑:我会尝试简化我的问题 - 为什么“DoSomethingWithDateTime”会编译,而“DoSomethingWithMyStruct”则没有。两个论点都是结构。

3 个答案:

答案 0 :(得分:4)

它知道结构永远不会为空(Nullable<T>除外);这足以发出警告。

在这个领域有一个已知的编译器问题,它出现在C#2.0编译器和C#3.0编译器之间(目前仍保留在C#4.0编译器中)[我不知道为什么你在VS2005上看到它虽然]。对于使用== / !=运算符的自定义结构,相等性测试不会引发无法访问代码警告。 DateTime有这些运营商;你的结构没有 - 因此不同。

这个问题是logged on connect,最近由编译器团队进行了研究(他们热衷于在机会出现时修复它)。

答案 1 :(得分:2)

因为DateTime是一个结构,所以它不能为空。并且没有办法以第二个参数为空的方式覆盖结构的==运算符。

答案 2 :(得分:2)

正如Hun1Ahpu所说,它永远不会为空。

但是,您可以提供自己的==运算符,它可以将对象作为参数类型,以允许上述代码进行编译。

显然,你需要它做一些合乎逻辑的事情。