Jep*_*sen 11 c# comparison nullable compiler-warnings lifted-operators
请考虑以下代码:
DateTime t = DateTime.Today;
bool isGreater = t > null;
Run Code Online (Sandbox Code Playgroud)
使用Visual Studio 2010(C#4,.NET 4.0),我收到以下警告:
警告CS0458:表达式的结果始终为'bool'类型的'null'
这是不正确的; 结果总是false(类型bool):
现在,struct DateTime重载>(大于)运算符.任何不可为空的结构(如DateTime)都可以隐式转换为相应的Nullable<>类型.上面的表达式完全相同
bool isGreater = (DateTime?)t > (DateTime?)null;
Run Code Online (Sandbox Code Playgroud)
这也产生了同样的错误警告.在这里,>操作员是提升的操作员.如果HasValue其两个操作数中的任何一个是,则返回false false.否则,提升的运算符将继续将两个操作数展开到底层结构,然后调用该>结构定义的重载(但在这种情况下,这不是必需的,其中一个操作数不是HasValue).
你能重现这个bug,这个bug是众所周知的吗?我误解了什么吗?
对于所讨论int的运算符重载的所有结构类型(不是简单类型,而不是枚举类型),这是相同的.
(现在如果我们使用==而不是>,那么一切都应该完全相似(因为DateTime也会使==运算符超载).但它不相似.如果我说
DateTime t = DateTime.Today;
bool isEqual = t == null;
Run Code Online (Sandbox Code Playgroud)
我没有得到警告☹有时候你会看到人们不小心检查变量或参数为null,没有意识到他们的变量类型是一个结构(它过载==而且不是一个简单的类型int).如果他们得到警告会更好.)
更新:使用Visual Studio 2015的C#6.0编译器(基于 Roslyn),isGreater上面的错误消息将更改为带有正确且有用的警告消息的CS0464.此外,isEqualVS2015的编译器修复了上述缺少警告,但只有在编译时才能修复/features:strict.
我在Roslyn中实现提升的操作员行为时独立发现了这个错误,我在离开之前在Roslyn中修复了它.
对不起,我在10月份发布时没有看到这个.感谢您将其提交给Connect!许多道歉的错误; 这是操作员语义分析中的一个长期错误.
顺便提一下,我将在本月晚些时候(2012年12月)讨论Roslyn如何在http://ericlippert.com上优化提升表达式,所以如果这个主题让你感兴趣,请查看:
http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/
你是对的:这是Visual Studio中的一个错误.C#4.0标准(第7.3.7节提升运营商)有这样的说法:
对于关系运算符
Run Code Online (Sandbox Code Playgroud)< > <= >=[...] 如果一个或两个操作数为空,则提升的运算符将生成值
false....
事实上,在MonoDevelop中,您会收到以下警告:
比较型的结果
System.DateTime与null始终false.
| 归档时间: |
|
| 查看次数: |
941 次 |
| 最近记录: |