考虑以下代码:
DateTime t = DateTime.Today;
bool isGreater = t > null;
使用 Visual Studio 2010(C# 4、.NET 4.0)时,我收到以下警告:
warning CS0458: The result of the expression is always 'null' of type 'bool?'
这是不正确的;结果总是 false
(类型为 bool
):
现在,结构 DateTime 重载了 >
(大于)运算符。任何不可为 null 的结构(如 DateTime)都可以隐式转换为相应的 Nullable<>
类型。上面的表达式完全等同于
bool isGreater = (DateTime?)t > (DateTime?)null;
这也会产生同样的错误警告。这里是>
运算符是提升运算符。这通过在 HasValue
时返回 false 来工作。它的两个操作数中的任何一个都是 false
.否则,提升运算符将继续将两个操作数解包到底层结构,然后调用 >
的重载。由该结构定义(但在一个操作数不是 HasValue
的情况下,这不是必需的)。
你能重现这个错误吗?这个错误是众所周知的吗?我是不是误解了什么?
这对于重载相关运算符的所有结构类型(不是像 int
这样的简单类型,也不是枚举类型)都是一样的。
(现在如果我们使用 ==
而不是 >
,一切都应该完全相似(因为 DateTime 也会重载 ==
运算符)。但它并不相似。如果我说
DateTime t = DateTime.Today;
bool isEqual = t == null;
我收到 no 警告 ☹ 有时你会看到人们不小心检查了一个变量或参数是否为空,没有意识到他们的变量类型是一个结构(它重载了 ==
而不是一个简单类型,如 int
)。如果他们得到警告会更好。)
更新:使用 Visual Studio 2015 的 C# 6.0 编译器(基于 Roslyn),错误消息 isGreater
上面已更改为 CS0464,其中包含正确且有用的警告消息。此外,缺少警告 isEqual
以上在 VS2015 的编译器中是固定的,但前提是你用 /features:strict
编译.
最佳答案
我在 Roslyn 中实现提升运算符行为时独立发现了这个错误,并在我离开之前在 Roslyn 中修复了它。
抱歉,您在 10 月份发布时我没有看到它。感谢您将其提交给 Connect!并为错误道歉;这是运算符语义分析中长期存在的错误。
顺便说一句,我将讨论 Roslyn 如何优化 http://ericlippert.com 上的提升表达式本月晚些时候(2012 年 12 月),如果您对这个主题感兴趣,请查看:
http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/
关于c# - 将 struct 与 null 进行比较时出现错误的编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13046115/